解决了语音上传到问题,接下来要解决下载播放问题

This commit is contained in:
joywayer
2025-06-15 12:36:47 +08:00
parent bba3ed1cb4
commit c11fc62bf1
513 changed files with 31197 additions and 2969 deletions

View File

@@ -0,0 +1,21 @@
//
// QNUploadServerDomainResolver.h
// AppTest
//
// Created by yangsen on 2020/4/23.
// Copyright © 2020 com.qiniu. All rights reserved.
//
#import "QNUploadRegionInfo.h"
NS_ASSUME_NONNULL_BEGIN
@class QNConfiguration;
@interface QNUploadDomainRegion : NSObject <QNUploadRegion>
- (instancetype)initWithConfig:(QNConfiguration *)config;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,444 @@
//
// QNUploadServerDomainResolver.m
// AppTest
//
// Created by yangsen on 2020/4/23.
// Copyright © 2020 com.qiniu. All rights reserved.
//
#import "QNUploadRequestState.h"
#import "QNUploadDomainRegion.h"
#import "QNResponseInfo.h"
#import "QNUploadServer.h"
#import "QNZoneInfo.h"
#import "QNUploadServerFreezeUtil.h"
#import "QNUploadServerFreezeManager.h"
#import "QNDnsPrefetch.h"
#import "QNLogUtil.h"
#import "QNUtils.h"
#import "QNDefine.h"
#import "QNUploadServerNetworkStatus.h"
@interface QNUploadIpGroup : NSObject
@property(nonatomic, assign)int ipIndex;
@property(nonatomic, copy, readonly)NSString *groupType;
@property(nonatomic, strong, readonly)NSArray <id <QNIDnsNetworkAddress> > *ipList;
@end
@implementation QNUploadIpGroup
- (instancetype)initWithGroupType:(NSString *)groupType
ipList:(NSArray <id <QNIDnsNetworkAddress> > *)ipList{
if (self = [super init]) {
_groupType = groupType;
_ipList = ipList;
_ipIndex = -1;
}
return self;
}
- (id <QNIDnsNetworkAddress>)getServerIP{
if (!self.ipList || self.ipList.count == 0) {
return nil;
} else {
if (_ipIndex < 0 || _ipIndex > (self.ipList.count - 1)) {
_ipIndex = arc4random()%self.ipList.count;
}
return self.ipList[_ipIndex];
}
}
@end
@interface QNUploadServerDomain: NSObject
@property(nonatomic, copy)NSString *host;
@property(nonatomic, strong)NSArray <QNUploadIpGroup *> *ipGroupList;
@end
@implementation QNUploadServerDomain
+ (QNUploadServerDomain *)domain:(NSString *)host{
QNUploadServerDomain *domain = [[QNUploadServerDomain alloc] init];
domain.host = host;
return domain;
}
- (QNUploadServer *)getServerWithCondition:(BOOL(^)(NSString *host, QNUploadServer *server, QNUploadServer *filterServer))condition {
@synchronized (self) {
if (!self.ipGroupList || self.ipGroupList.count == 0) {
[self createIpGroupList];
}
}
QNUploadServer *server = nil;
// HostIP:
if (self.ipGroupList && self.ipGroupList.count > 0) {
for (QNUploadIpGroup *ipGroup in self.ipGroupList) {
id <QNIDnsNetworkAddress> inetAddress = [ipGroup getServerIP];
QNUploadServer *filterServer = [QNUploadServer server:self.host
ip:inetAddress.ipValue
source:inetAddress.sourceValue
ipPrefetchedTime:inetAddress.timestampValue];
if (condition == nil || condition(self.host, server, filterServer)) {
server = filterServer;
}
if (condition == nil) {
break;
}
}
return server;
}
// HostIP:
QNUploadServer *hostServer = [QNUploadServer server:self.host
ip:nil
source:nil
ipPrefetchedTime:nil];
if (condition == nil || condition(self.host, nil, hostServer)) {
//
server = hostServer;
}
return server;
}
- (QNUploadServer *)getOneServer{
if (!self.host || self.host.length == 0) {
return nil;
}
if (self.ipGroupList && self.ipGroupList.count > 0) {
NSInteger index = arc4random()%self.ipGroupList.count;
QNUploadIpGroup *ipGroup = self.ipGroupList[index];
id <QNIDnsNetworkAddress> inetAddress = [ipGroup getServerIP];
QNUploadServer *server = [QNUploadServer server:self.host ip:inetAddress.ipValue source:inetAddress.sourceValue ipPrefetchedTime:inetAddress.timestampValue];;
return server;
} else {
return [QNUploadServer server:self.host ip:nil source:nil ipPrefetchedTime:nil];
}
}
- (void)clearIpGroupList {
@synchronized (self) {
self.ipGroupList = nil;
}
}
- (void)createIpGroupList {
@synchronized (self) {
if (self.ipGroupList && self.ipGroupList.count > 0) {
return;
}
// get address List of host
NSArray *inetAddresses = [kQNDnsPrefetch getInetAddressByHost:self.host];
if (!inetAddresses || inetAddresses.count == 0) {
return;
}
// address List to ipList of group & check ip network
NSMutableDictionary *ipGroupInfos = [NSMutableDictionary dictionary];
for (id <QNIDnsNetworkAddress> inetAddress in inetAddresses) {
NSString *ipValue = inetAddress.ipValue;
NSString *groupType = [QNUtils getIpType:ipValue host:self.host];
if (groupType) {
NSMutableArray *ipList = ipGroupInfos[groupType] ?: [NSMutableArray array];
[ipList addObject:inetAddress];
ipGroupInfos[groupType] = ipList;
}
}
// ipList of group to ipGroup List
NSMutableArray *ipGroupList = [NSMutableArray array];
for (NSString *groupType in ipGroupInfos.allKeys) {
NSArray *ipList = ipGroupInfos[groupType];
QNUploadIpGroup *ipGroup = [[QNUploadIpGroup alloc] initWithGroupType:groupType ipList:ipList];
[ipGroupList addObject:ipGroup];
}
self.ipGroupList = ipGroupList;
}
}
@end
@interface QNUploadDomainRegion()
// http3
@property(nonatomic, assign)BOOL http3Enabled;
// HostPS Host, Region -9
@property(atomic , assign)BOOL hasFreezeHost;
@property(atomic , assign)BOOL isAllFrozen;
@property(atomic , assign)BOOL enableAccelerateUpload;
// http2
@property(nonatomic, strong)QNUploadServerFreezeManager *partialHttp2Freezer;
@property(nonatomic, strong)QNUploadServerFreezeManager *partialHttp3Freezer;
@property(nonatomic, strong)NSArray <NSString *> *accDomainHostList;
@property(nonatomic, strong)NSDictionary <NSString *, QNUploadServerDomain *> *accDomainDictionary;
@property(nonatomic, strong)NSArray <NSString *> *domainHostList;
@property(nonatomic, strong)NSDictionary <NSString *, QNUploadServerDomain *> *domainDictionary;
@property(nonatomic, strong)NSArray <NSString *> *oldDomainHostList;
@property(nonatomic, strong)NSDictionary <NSString *, QNUploadServerDomain *> *oldDomainDictionary;
@property(nonatomic, strong, nullable)QNZoneInfo *zoneInfo;
@end
@implementation QNUploadDomainRegion
- (instancetype)initWithConfig:(QNConfiguration *)config {
if (self = [super init]) {
if (config) {
self.enableAccelerateUpload = config.accelerateUploading;
}
}
return self;
}
- (BOOL)isValid{
return !self.isAllFrozen &&
((self.enableAccelerateUpload && self.accDomainHostList > 0) ||
self.domainHostList.count > 0 || self.oldDomainHostList.count > 0);
}
- (void)setupRegionData:(QNZoneInfo *)zoneInfo{
_zoneInfo = zoneInfo;
self.isAllFrozen = NO;
self.hasFreezeHost = NO;
self.http3Enabled = zoneInfo.http3Enabled;
//
self.http3Enabled = false;
NSMutableArray *serverGroups = [NSMutableArray array];
NSMutableArray *accDomainHostList = [NSMutableArray array];
if (zoneInfo.acc_domains) {
[serverGroups addObjectsFromArray:zoneInfo.acc_domains];
[accDomainHostList addObjectsFromArray:zoneInfo.acc_domains];
}
self.accDomainHostList = accDomainHostList;
self.accDomainDictionary = [self createDomainDictionary:serverGroups];
[serverGroups removeAllObjects];
NSMutableArray *domainHostList = [NSMutableArray array];
if (zoneInfo.domains) {
[serverGroups addObjectsFromArray:zoneInfo.domains];
[domainHostList addObjectsFromArray:zoneInfo.domains];
}
self.domainHostList = domainHostList;
self.domainDictionary = [self createDomainDictionary:serverGroups];
[serverGroups removeAllObjects];
NSMutableArray *oldDomainHostList = [NSMutableArray array];
if (zoneInfo.old_domains) {
[serverGroups addObjectsFromArray:zoneInfo.old_domains];
[oldDomainHostList addObjectsFromArray:zoneInfo.old_domains];
}
self.oldDomainHostList = oldDomainHostList;
self.oldDomainDictionary = [self createDomainDictionary:serverGroups];
QNLogInfo(@"region :%@",domainHostList);
QNLogInfo(@"region old:%@",oldDomainHostList);
}
- (NSDictionary *)createDomainDictionary:(NSArray <NSString *> *)hosts{
NSMutableDictionary *domainDictionary = [NSMutableDictionary dictionary];
for (NSString *host in hosts) {
QNUploadServerDomain *domain = [QNUploadServerDomain domain:host];
[domainDictionary setObject:domain forKey:host];
}
return [domainDictionary copy];
}
- (void)updateIpListFormHost:(NSString *)host {
if (host == nil) {
return;
}
[self.domainDictionary[host] clearIpGroupList];
[self.oldDomainDictionary[host] clearIpGroupList];
}
- (id<QNUploadServer> _Nullable)getNextServer:(QNUploadRequestState *)requestState
responseInfo:(QNResponseInfo *)responseInfo
freezeServer:(id <QNUploadServer> _Nullable)freezeServer{
if (self.isAllFrozen) {
return nil;
}
[self freezeServerIfNeed:responseInfo freezeServer:freezeServer];
BOOL accelerate = YES;
@synchronized (self) {
if (self.enableAccelerateUpload && responseInfo.isTransferAccelerationConfigureError) {
self.enableAccelerateUpload = NO;
}
accelerate = self.enableAccelerateUpload;
}
NSMutableArray *hostList = [NSMutableArray array];
NSMutableDictionary *domainInfo = [NSMutableDictionary dictionary];
if (requestState.isUseOldServer) {
if (self.oldDomainHostList.count > 0 && self.oldDomainDictionary.count > 0) {
[hostList addObjectsFromArray:self.oldDomainHostList];
[domainInfo addEntriesFromDictionary:self.oldDomainDictionary];
}
} else {
// 使 acc
if (accelerate &&
self.accDomainHostList.count > 0 &&
self.accDomainDictionary.count > 0) {
[hostList addObjectsFromArray:self.accDomainHostList];
[domainInfo addEntriesFromDictionary:self.accDomainDictionary];
}
if (self.domainHostList.count > 0 &&
self.domainDictionary.count > 0){
[hostList addObjectsFromArray:self.domainHostList];
[domainInfo addEntriesFromDictionary:self.domainDictionary];
}
}
if (hostList.count == 0 || domainInfo.count == 0) {
return nil;
}
QNUploadServer *server = nil;
// 1. 使http3
if (self.http3Enabled) {
for (NSString *host in hostList) {
QNUploadServer *domainServer = [domainInfo[host] getServerWithCondition:^BOOL(NSString *host, QNUploadServer *serverP, QNUploadServer *filterServer) {
// 1.1
NSString *frozenType = QNUploadFrozenType(host, filterServer.ip);
BOOL isFrozen = [QNUploadServerFreezeUtil isType:frozenType
frozenByFreezeManagers:@[self.partialHttp3Freezer, kQNUploadGlobalHttp3Freezer]];
if (isFrozen) {
return NO;
}
// 1.2
return [QNUploadServerNetworkStatus isServerNetworkBetter:filterServer thanServerB:serverP];
}];
server = [QNUploadServerNetworkStatus getBetterNetworkServer:server serverB:domainServer];
if (server) {
break;
}
}
if (server) {
server.httpVersion = kQNHttpVersion3;
return server;
}
}
// 2. http2
for (NSString *host in hostList) {
kQNWeakSelf;
QNUploadServer *domainServer = [domainInfo[host] getServerWithCondition:^BOOL(NSString *host, QNUploadServer *serverP, QNUploadServer *filterServer) {
kQNStrongSelf;
// 2.1
NSString *frozenType = QNUploadFrozenType(host, filterServer.ip);
BOOL isFrozen = [QNUploadServerFreezeUtil isType:frozenType
frozenByFreezeManagers:@[self.partialHttp2Freezer, kQNUploadGlobalHttp2Freezer]];
if (isFrozen) {
return NO;
}
// 2.2
return [QNUploadServerNetworkStatus isServerNetworkBetter:filterServer thanServerB:serverP];
}];
server = [QNUploadServerNetworkStatus getBetterNetworkServer:server serverB:domainServer];
if (server) {
break;
}
}
// 3. server Host
if (server == nil && !self.hasFreezeHost && hostList.count > 0) {
NSInteger index = arc4random()%hostList.count;
NSString *host = hostList[index];
server = [domainInfo[host] getOneServer];
[self unfreezeServer:server];
}
if (server == nil) {
self.isAllFrozen = YES;
}
server.httpVersion = kQNHttpVersion2;
QNLogInfo(@"get server host:%@ ip:%@", server.host, server.ip);
return server;
}
- (void)freezeServerIfNeed:(QNResponseInfo *)responseInfo
freezeServer:(QNUploadServer *)freezeServer {
if (freezeServer == nil || freezeServer.serverId == nil || responseInfo == nil) {
return;
}
NSString *frozenType = QNUploadFrozenType(freezeServer.host, freezeServer.ip);
// 1. http3
if (kQNIsHttp3(freezeServer.httpVersion)) {
if (responseInfo.isNotQiniu) {
self.hasFreezeHost = YES;
[self.partialHttp3Freezer freezeType:frozenType frozenTime:kQNGlobalConfiguration.partialHostFrozenTime];
}
if (!responseInfo.canConnectToHost || responseInfo.isHostUnavailable) {
self.hasFreezeHost = YES;
[kQNUploadGlobalHttp3Freezer freezeType:frozenType frozenTime:kQNUploadHttp3FrozenTime];
}
return;
}
// 2. http2
// 2.1 Host || Host
if (responseInfo.isNotQiniu || !responseInfo.canConnectToHost || responseInfo.isHostUnavailable) {
QNLogInfo(@"partial freeze server host:%@ ip:%@", freezeServer.host, freezeServer.ip);
self.hasFreezeHost = YES;
[self.partialHttp2Freezer freezeType:frozenType frozenTime:kQNGlobalConfiguration.partialHostFrozenTime];
}
// 2.2 Host
if (responseInfo.isHostUnavailable) {
QNLogInfo(@"global freeze server host:%@ ip:%@", freezeServer.host, freezeServer.ip);
self.hasFreezeHost = YES;
[kQNUploadGlobalHttp2Freezer freezeType:frozenType frozenTime:kQNGlobalConfiguration.globalHostFrozenTime];
}
}
///
- (void)unfreezeServer:(QNUploadServer *)freezeServer {
if (freezeServer == nil) {
return;
}
NSString *frozenType = QNUploadFrozenType(freezeServer.host, freezeServer.ip);
[self.partialHttp2Freezer unfreezeType:frozenType];
}
- (QNUploadServerFreezeManager *)partialHttp2Freezer{
if (!_partialHttp2Freezer) {
_partialHttp2Freezer = [[QNUploadServerFreezeManager alloc] init];
}
return _partialHttp2Freezer;
}
- (QNUploadServerFreezeManager *)partialHttp3Freezer{
if (!_partialHttp3Freezer) {
_partialHttp3Freezer = [[QNUploadServerFreezeManager alloc] init];
}
return _partialHttp3Freezer;
}
@end

View File

@@ -0,0 +1,29 @@
//
// QNUploadServer.h
// AppTest
//
// Created by yangsen on 2020/4/23.
// Copyright © 2020 com.qiniu. All rights reserved.
//
#import "QNUploadRegionInfo.h"
NS_ASSUME_NONNULL_BEGIN
@interface QNUploadServer : NSObject <QNUploadServer>
@property(nonatomic, copy)NSString *httpVersion;
/// 上传server构造方法
/// @param host host
/// @param ip host对应的IP
/// @param source ip查询来源@"system"@"httpdns" @"none" @"customized" 自定义请使用@"customized"
/// @param ipPrefetchedTime 根据host获取IP的时间戳
+ (instancetype)server:(NSString * _Nullable)host
ip:(NSString * _Nullable)ip
source:(NSString * _Nullable)source
ipPrefetchedTime:(NSNumber * _Nullable)ipPrefetchedTime;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,39 @@
//
// QNUploadServer.m
// AppTest
//
// Created by yangsen on 2020/4/23.
// Copyright © 2020 com.qiniu. All rights reserved.
//
#import "QNUploadServer.h"
@interface QNUploadServer()
@property(nonatomic, copy)NSString *ip;
@property(nonatomic, copy)NSString *host;
@property(nonatomic, copy)NSString *source;
@property(nonatomic,strong)NSNumber *ipPrefetchedTime;
@end
@implementation QNUploadServer
@synthesize httpVersion;
+ (instancetype)server:(NSString *)host
ip:(NSString *)ip
source:(NSString *)source
ipPrefetchedTime:(NSNumber *)ipPrefetchedTime{
QNUploadServer *server = [[QNUploadServer alloc] init];
server.ip = ip;
server.host = host;
server.source = source ?: @"none";
server.httpVersion = kQNHttpVersion2;
server.ipPrefetchedTime = ipPrefetchedTime;
return server;
}
- (NSString *)serverId {
return [self.host copy];
}
@end

View File

@@ -0,0 +1,30 @@
//
// QNUploadServerFreezeManager.h
// QiniuSDK
//
// Created by yangsen on 2020/6/2.
// Copyright © 2020 Qiniu. All rights reserved.
//
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface QNUploadServerFreezeManager : NSObject
/// 查询host是否被冻结
/// @param type 冻结Key
- (BOOL)isTypeFrozen:(NSString * _Nullable)type;
/// 冻结host
/// @param type 冻结Key
/// @param frozenTime 冻结时间
- (void)freezeType:(NSString * _Nullable)type frozenTime:(NSInteger)frozenTime;
/// 解冻host
/// @param type 冻结Key
- (void)unfreezeType:(NSString * _Nullable)type;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,97 @@
//
// QNUploadServerFreezeManager.m
// QiniuSDK
//
// Created by yangsen on 2020/6/2.
// Copyright © 2020 Qiniu. All rights reserved.
//
#import "QNConfiguration.h"
#import "QNUploadServerFreezeManager.h"
@interface QNUploadServerFreezeItem : NSObject
@property(nonatomic, copy)NSString *type;
@property(nonatomic, strong)NSDate *freezeDate;
@end
@implementation QNUploadServerFreezeItem
+ (instancetype)item:(NSString *)type{
QNUploadServerFreezeItem *item = [[QNUploadServerFreezeItem alloc] init];
item.type = type;
return item;
}
- (BOOL)isFrozenByDate:(NSDate *)date{
BOOL isFrozen = YES;
@synchronized (self) {
if (!self.freezeDate || [self.freezeDate timeIntervalSinceDate:date] < 0){
isFrozen = NO;
}
}
return isFrozen;
}
- (void)freeze:(NSInteger)frozenTime{
@synchronized (self) {
self.freezeDate = [NSDate dateWithTimeIntervalSinceNow:frozenTime];
}
}
@end
@interface QNUploadServerFreezeManager()
@property(nonatomic, strong)NSMutableDictionary *freezeInfo;
@end
@implementation QNUploadServerFreezeManager
- (instancetype)init{
if (self = [super init]) {
_freezeInfo = [NSMutableDictionary dictionary];
}
return self;
}
- (BOOL)isTypeFrozen:(NSString * _Nullable)type {
if (!type || type.length == 0) {
return true;
}
BOOL isFrozen = true;
QNUploadServerFreezeItem *item = nil;
@synchronized (self) {
item = self.freezeInfo[type];
}
if (!item || ![item isFrozenByDate:[NSDate date]]) {
isFrozen = false;
}
return isFrozen;
}
- (void)freezeType:(NSString * _Nullable)type frozenTime:(NSInteger)frozenTime {
if (!type || type.length == 0) {
return;
}
QNUploadServerFreezeItem *item = nil;
@synchronized (self) {
item = self.freezeInfo[type];
if (!item) {
item = [QNUploadServerFreezeItem item:type];
self.freezeInfo[type] = item;
}
}
[item freeze:frozenTime];
}
- (void)unfreezeType:(NSString * _Nullable)type {
if (!type || type.length == 0) {
return;
}
@synchronized (self) {
[self.freezeInfo removeObjectForKey:type];
}
}
@end

View File

@@ -0,0 +1,31 @@
//
// QNUploadServerFreezeUtil.h
// QiniuSDK
//
// Created by yangsen on 2021/2/4.
// Copyright © 2021 Qiniu. All rights reserved.
//
#import "QNUploadServerFreezeManager.h"
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
#define kQNUploadHttp3FrozenTime (3600 * 24)
#define QNUploadFrozenType(HOST, IP) ([QNUploadServerFreezeUtil getFrozenType:HOST ip:IP])
#define kQNUploadGlobalHttp3Freezer [QNUploadServerFreezeUtil sharedHttp3Freezer]
#define kQNUploadGlobalHttp2Freezer [QNUploadServerFreezeUtil sharedHttp2Freezer]
@interface QNUploadServerFreezeUtil : NSObject
+ (QNUploadServerFreezeManager *)sharedHttp2Freezer;
+ (QNUploadServerFreezeManager *)sharedHttp3Freezer;
+ (BOOL)isType:(NSString *)type frozenByFreezeManagers:(NSArray <QNUploadServerFreezeManager *> *)freezeManagerList;
+ (NSString *)getFrozenType:(NSString *)host ip:(NSString *)ip;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,55 @@
//
// QNUploadServerFreezeUtil.m
// QiniuSDK
//
// Created by yangsen on 2021/2/4.
// Copyright © 2021 Qiniu. All rights reserved.
//
#import "QNUtils.h"
#import "QNUploadServerFreezeUtil.h"
@implementation QNUploadServerFreezeUtil
+ (QNUploadServerFreezeManager *)sharedHttp2Freezer {
static QNUploadServerFreezeManager *manager = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
manager = [[QNUploadServerFreezeManager alloc] init];
});
return manager;
}
+ (QNUploadServerFreezeManager *)sharedHttp3Freezer {
static QNUploadServerFreezeManager *manager = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
manager = [[QNUploadServerFreezeManager alloc] init];
});
return manager;
}
+ (BOOL)isType:(NSString *)type frozenByFreezeManagers:(NSArray <QNUploadServerFreezeManager *> *)freezeManagerList{
if (!type || type.length == 0) {
return YES;
}
if (!freezeManagerList || freezeManagerList.count == 0) {
return NO;
}
BOOL isFrozen = NO;
for (QNUploadServerFreezeManager *freezeManager in freezeManagerList) {
isFrozen = [freezeManager isTypeFrozen:type];
if (isFrozen) {
break;
}
}
return isFrozen;
}
+ (NSString *)getFrozenType:(NSString *)host ip:(NSString *)ip {
NSString *ipType = [QNUtils getIpType:ip host:host];
return [NSString stringWithFormat:@"%@-%@", host, ipType];
}
@end