Ios NSURLSession Exchange server拒绝了多个并发请求
我已将我的Ios NSURLSession Exchange server拒绝了多个并发请求,ios,concurrency,exchangewebservices,nsurlsession,Ios,Concurrency,Exchangewebservices,Nsurlsession,我已将我的NSURLConnection代码替换为nsursession,以便使用EWS Exchange server获取数据。我的应用程序进行多个并发API调用。它工作正常,但现在,当我使用NSURLSession时,我的一些API调用得到了正确的响应,一些API调用从exchange server得到错误,如下所示: { "s:Envelope" = { "s:Body" = { "m:GetItemResponse" =
NSURLConnection
代码替换为nsursession
,以便使用EWS Exchange server获取数据。我的应用程序进行多个并发API调用。它工作正常,但现在,当我使用NSURLSession
时,我的一些API调用得到了正确的响应,一些API调用从exchange server得到错误,如下所示:
{
"s:Envelope" = {
"s:Body" = {
"m:GetItemResponse" = {
"m:ResponseMessages" = {
"m:GetItemResponseMessage" = {
ResponseClass = Error;
"m:DescriptiveLinkKey" = {
text = 0;
};
"m:Items" = {
};
"m:MessageText" = {
text = "An internal server error occurred. The operation failed., Cannot open mailbox /o=First Organization/ou=Exchange Administrative Group(FYDIBOHF23SPDLT)/cn=Recipients/cn=00037FFEE6F0D3D2.";
};
"m:MessageXml" = {
"t:Value" = (
{
Name = InnerErrorMessageText;
text = "Too many concurrent connections opened.";
},
{
Name = InnerErrorResponseCode;
text = ErrorTooManyObjectsOpened;
},
{
Name = InnerErrorDescriptiveLinkKey;
text = 0;
}
);
};
"m:ResponseCode" = {
text = ErrorInternalServerError;
};
};
};
"xmlns:m" = "http://schemas.microsoft.com/exchange/services/2006/messages";
"xmlns:t" = "http://schemas.microsoft.com/exchange/services/2006/types";
};
"xmlns:xsd" = "http://www.w3.org/2001/XMLSchema";
"xmlns:xsi" = "http://www.w3.org/2001/XMLSchema-instance";
};
"s:Header" = {
"h:ServerVersionInfo" = {
MajorBuildNumber = 1034;
MajorVersion = 15;
MinorBuildNumber = 11;
MinorVersion = 1;
xmlns = "http://schemas.microsoft.com/exchange/services/2006/types";
"xmlns:h" = "http://schemas.microsoft.com/exchange/services/2006/types";
"xmlns:xsd" = "http://www.w3.org/2001/XMLSchema";
"xmlns:xsi" = "http://www.w3.org/2001/XMLSchema-instance";
};
};
"xmlns:s" = "http://schemas.xmlsoap.org/soap/envelope/";
};
显然,问题是同时连接太多
我的代码流是:
我的HTTPRequest.m
有一个方法
- (void)fetchData
{
dispatch_async(dispatch_get_main_queue(), ^{
sessionAlive = sessionAlive + 1;
NSLog(@"sessionCount: %ld", (long)sessionAlive);
NSURLSessionConfiguration *defaultConfiguration = [NSURLSessionConfiguration ephemeralSessionConfiguration];
NSURLSession *defaultSession = [NSURLSession sessionWithConfiguration:defaultConfiguration
delegate:self
delegateQueue:nil];
NSURLSessionDataTask *dataTask = [defaultSession dataTaskWithRequest:request];
[dataTask resume];
});
}
// Some NSURLSession delegates methods here
-(void)URLSession:(NSURLSession *)session
dataTask:(NSURLSessionDataTask *)dataTask
didReceiveData:(NSData *)data
{
[self.data appendData:data];
}
-(void)URLSession:(NSURLSession *)session
task:(NSURLSessionTask *)task
didCompleteWithError:(NSError *)error
{
if (error)
{
self.failureBlock ? self.failureBlock(error) : nil;
}
else
{
NSData *data;
if (self.data)
{
data = [NSData dataWithData:self.data];
}
self.successBlock ? self.successBlock(self.redirectLocation, data) : nil;
}
[session finishTasksAndInvalidate]; // We must release the session, else it holds strong referance for it's delegate (in our case EWSHTTPRequest).
// And it wont allow the delegate object to free -> cause memory leak
}
我正在同时下载类似这样的电子邮件:
dispatch_queue_t backgroundQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0);
dispatch_async(backgroundQueue, ^{
foreach (NSString *emailId in emalilIDArray)
{
HTTPRequest *request = [HTTPRequest alloc] init];
[request fetchData];
}
});
我想我的问题是每次打电话我都会打电话,但我不知道该怎么办
如果我不能使用共享实例会话,因为我需要将会话的委托与每个HTTPRequest对象关联以处理响应
有什么建议或更好的方法吗?为了最大限度地减少体系结构的更改,我可能会建议使用一个单例来管理会话,但代理对相关对象的委托调用。换言之:
NSURLRequest
对该单例类调用一个方法,并让它创建任务;将您的HTTPRequest
对象也传递给该方法,以便它知道使用结果调用谁NSURLSession[Data | Download | Upload]任务
对象作为键存储在字典中HTTPRequest
对象存储为相应的值HTTPRequest
对象上调用相同的委托方法HTTPRequest
对象另一方面,如果所有的<代码> HTTPRequest < /Cord>对象正在做的是提供一组身份验证处理方法并积累数据,您可以考虑创建一个Stutelon类,该类使用一个<代码> NSURLRequest <代码>对象和一个块,并在您获得数据时运行该块。
因此,如果不以增量方式处理数据,您还可以考虑将该块直接作为任务的
dispatch_async(backgroundQueue, ^{...
您可以使用相同的块创建NSBlockOperation,并将此操作添加到NSOperationQueue。如果您添加的任务超过“operationCount”,则只会发出“operationCount”请求。所有其他人将在其中一个已执行任务完成时等待
这不是完整的代码,而是您可以尝试的想法
NSOperationQueue *backgroundOperationQueue = [[NSOperationQueue alloc] init];
backgroundOperationQueue.operationCount = 5;
NSOperation *blockOperation = [NSBlockOperation blockOperationWithBlock:yourblock];
[backgroundOperationQueue addOperation:blockOperation];
如果你喜欢GCD,考虑使用串行队列,它只允许一个任务在时间。< /P>
dispatch_queue_t queue;
queue = dispatch_queue_create("com.example.MyQueue", NULL);