使用 AFNetworking 同时处理数百个请求
Posted
技术标签:
【中文标题】使用 AFNetworking 同时处理数百个请求【英文标题】:Hit hundreds of requests concurrently using AFNetworking 【发布时间】:2016-09-24 18:54:56 【问题描述】:我需要同时处理数百个请求才能上传文件。我正在使用 AFNetworking,我只是从 for 循环中调用一个方法。但它在某些文件中给了我内部服务器错误。服务器端什么都没有。此过程已从 Web 成功执行。
这是我的代码:
for (UIImage *img in imgages)
[self uploadImage:img];
-(void) uploadImage:(UIImage *)image
// NSDictionary *someData=@x:x
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:someData
options:0
error:nil];
NSMutableURLRequest *request = [[AFHTTPRequestSerializer serializer] multipartFormRequestWithMethod:@"POST" URLString:[BASE_URL stringByAppendingString:@"xyz.com"] parameters:nil constructingBodyWithBlock:^(id<AFMultipartFormData> formData)
[formData appendPartWithFormData:jsonData name:@"abc"];
if (imgData)
[formData appendPartWithFormData:imgData name:@"file"];
error:nil];
AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
NSURLSessionUploadTask *uploadTask;
manager.responseSerializer = [AFHTTPResponseSerializer serializer];
uploadTask = [manager
uploadTaskWithStreamedRequest:request
progress:nil completionHandler:^(NSURLResponse * _Nonnull response, id _Nullable responseObject, NSError * _Nullable error)
];
[uploadTask resume];
实现上述功能的最佳方式是什么?
【问题讨论】:
您收到的确切错误是什么? ios 有每个主机的并发请求限制,但如果这是您遇到的情况,您将因请求过多而超时。 尝试使用dispatch_apply
而不是fo-loop
@Vikas 如果它有效,请接受答案
【参考方案1】:
尝试使用以下代码同时上传文件。
-(id)init
self = [super init];
if(self)
backgroundQueue = dispatch_queue_create("com.bgqueue", NULL);
dispatch_once(&onceToken, ^
NSURLSessionConfiguration *sessionConfiguration = [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:@"com.Demo-Upload"];
sessionConfiguration.HTTPMaximumConnectionsPerHost = 10;
manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:sessionConfiguration];
);
return self;
- (void)processFiles
for (UIImage *img in imgages)
dispatch_async(backgroundQueue, ^(void)
[self uploadImage:img];
);
-(void) uploadImage:(UIImage *)image
// Prepare a temporary file to store the multipart request prior to sending it to the server due to an alleged
// bug in NSURLSessionTask.
NSString* tmpFilename = [NSString stringWithFormat:@"%f", [NSDate timeIntervalSinceReferenceDate]];
NSURL* tmpFileUrl = [NSURL fileURLWithPath:[NSTemporaryDirectory() stringByAppendingPathComponent:tmpFilename]];
// Create a multipart form request.
NSMutableURLRequest *request = [[AFHTTPRequestSerializer serializer] multipartFormRequestWithMethod:@"POST" URLString:[BASE_URL stringByAppendingString:@"xyz.com"] parameters:nil constructingBodyWithBlock:^(id<AFMultipartFormData> formData)
[formData appendPartWithFormData:jsonData name:@"abc"];
if (imgData)
[formData appendPartWithFormData:imgData name:@"file"];
error:nil];
// Dump multipart request into the temporary file.
[[AFHTTPRequestSerializer serializer] requestWithMultipartFormRequest:request
writingStreamContentsToFile:tmpFileUrl
completionHandler:^(NSError *error)
// Once the multipart form is serialized into a temporary file, we can initialize
// the actual HTTP request using session manager.
// Here note that we are submitting the initial multipart request. We are, however,
// forcing the body stream to be read from the temporary file.
self.uploadTask = [manager uploadTaskWithRequest:request
fromFile:tmpFileUrl
progress:^(NSProgress * _Nonnull uploadProgress)
NSLog(@"Progress… %f", uploadProgress.fractionCompleted);
completionHandler:^(NSURLResponse *response, id responseObject, NSError *error)
// Cleanup: remove temporary file.
[[NSFileManager defaultManager] removeItemAtURL:tmpFileUrl error:nil];
// Do something with the result.
if (error)
//Print Error
else
//Print responseObject
];
// Start the file upload.
[self.uploadTask resume];
];
当应用程序进入后台时,上述功能将继续上传图像。因此,这不会给您内部服务器错误或任何超时错误。
希望对您有所帮助。如果您对上述代码有任何疑问,请随时提问。
【讨论】:
以上是关于使用 AFNetworking 同时处理数百个请求的主要内容,如果未能解决你的问题,请参考以下文章
在 Firebase Cloud Messaging 上订阅数百个主题时,iOS 应用程序崩溃
如何在网页中同时传播数百个带有动画和交互式 webgl 上下文的小画布?