设置
我的程序中有两个区域-branch 1
和branch 2
-在其中每个区域一次异步发出1个并发GET请求的网络请求。每次发送1个请求,因为对于任何向服务器发出请求的用户,服务器的宽限期只有几毫秒。一次运行1个并发请求旨在帮助该宽限期。
进行此操作的目的是,如果在任何分支中任何请求失败,则可以再次重发该请求。
问题:
当我彼此分开运行这些分支时(即不同时运行),服务器很高兴。但是,一旦我允许两个操作同时发生,服务器就会引发429
错误,该错误是让用户知道there are too many requests coming in at any one time
的错误。然后发生的是一半的请求失败,然后由于故障安全,请求再次发送以进行处理,直到全部完成为止。
代表用户的数据包浪费时间和资源。
场景Branch 1
发送10个请求(通常在数千个请求中,一次处理一个,但为简单起见,我们将其保持在10个)。
这10个请求将非常快地一次并发处理一次,并返回其适当的数据对象。
现在,如果我们再次运行branch 1
操作-并发10个请求,然后添加branch 2's
10个请求,这将创建20个请求操作-数量增加一倍-移出服务器,这将导致分支1和2的大约一半请求失败,然后启用故障保护以重新发送那些请求操作。号泣。
问题
不管这两个分支位于我的应用程序中的什么位置,有没有一种方法可以将这些请求操作从我的应用程序中传递出去,以便我们可以控制和限制发送到服务器的请求操作,从而不会对服务器造成轰炸仅对于一半的请求失败?
可能的解决方案
我曾经想到的一个想法是创建一个单例,该单例将充当队列以及瓶颈,使我可以在代码库中的任何位置添加来自任何分支的请求操作-因此,为什么我认为单例是一个好主意为此-然后,一旦意识到请求操作已添加到队列中,然后使该队列一次运行1个并发请求。
我认为这对于我的目的将非常有用,我只是不知道如何处理请求的完成块,因为Branch 1
的请求操作与Branch 2
的请求操作的完成块不同。
您将如何处理?我们可以做些什么吗?
编辑1-我目前在做什么
在分支1中-使用AFHTTPOperation:
1)对于每个进程,我创建一个for循环,该循环迭代10次,将10 AFHTTPRequestOperation
添加到名为NSMutableArray
类型的名为multiOperations的本地数组中。
2)然后我将multipleOperations数组添加到batchOfRequestOperations方法中,如下所示:
NSArray *operations = [AFURLConnectionOperation batchOfRequestOperations:muiltipleOperations
progressBlock:^(NSUInteger numberOfFinishedOperations, NSUInteger totalNumberOfOperations){
//Do some stuff here for each iteration
}
completionBlock:^(NSArray*operations){
//Call the method that repeats this process again.
}];
[[NSOperationQueue mainQueue] addOperationsperations waitUntilFinished:NO];
AFHTTPSessionManager
创建NSURLSessionDataTasks
..该代码不会在for循环中运行,而是调用自己的方法,以便每次请求执行其自己的完成块时都会发出另一个请求。因此,分支2中的上一个请求完成后,它将永远永远保持自身调用。这就是我知道它一次仅运行1个请求的方式。这样很好。HTTPRequestOperationManager
有人可以告诉我如何正确完成操作吗?根据您的编辑,我可以看到您可能需要更改的一些内容。首先,是的,如果您同时使用AFHTTPOperation
或NSURLSessionDataTask
,但不同时使用两者,则将更加容易。
如果要使用AFHTTPOperation
,则不要对[NSOperationQueue mainQueue]
进行操作排队。原因是那是主要的UI队列,您不希望网络操作阻止它。您应该做的是创建自己的NSOperationQueue
并将其并发设置为1。
NSOperationQueue *networkQueue = [[NSOperationQueue alloc] init];
networkQueue.maxConcurrentOperationCount = 1;
NSURLSessionDataTask
与AFHTTPSessionManager
一起使用而不是。 AFNetworking的文档状态:AFHTTPSessionManager
的子类,该方法创建一个用自定义NSURLSessionConfiguration
初始化的实例。您可以配置NSURLSessionConfiguration
,但是它适合您的应用程序,但是您对此特定问题感兴趣的主要属性是 HTTPMaximumConnectionsPerHost
:1
,您可以让AFHTTPSessionManager
(实际上是NSURLSession
)担心确保在任何给定时间仅对您的服务器发出一个请求。@interface AppHTTPSessionManager : AFHTTPSessionManager
+ (instancetype)appSession;
@end
@implementation AppHTTPSessionManager
+ (instancetype)appSession {
static AppHTTPSessionManager *_appSession = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
configuration.HTTPMaximumConnectionsPerHost = 1;
_appSession = [[AppHTTPSessionManager alloc] initWithSessionConfiguration:configuration];
});
return _appSession;
}
@end
NSURLSessionDataTask
创建[AppHTTPSessionManager appSession]
。如果这样做,这些任务应该自动被限制为一次向服务器发出一个请求。
关于ios - AFNetworking请求操作-创建 channel /瓶颈队列单例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26689177/
欢迎光临 OStack程序员社区-中国程序员成长平台 (https://ostack.cn/) | Powered by Discuz! X3.4 |