菜鸟教程小白 发表于 2022-12-12 13:18:59

ios - NSURLSession 多个并发请求被 Exchange 服务器拒绝


                                            <p><p>我已将 <code>NSURLConnection</code> 代码替换为 <code>NSURLSession</code> 以使用 EWS Exchange 服务器获取数据。我的应用程序进行了多个并发 API 调用。它工作正常,但现在,当我使用 <code>NSURLSession</code> 时,我的一些 API 调用得到正确的响应,而一些从交换服务器得到错误,如下所示:</p>

<pre><code>{
&#34;s:Envelope&#34; =   {
    &#34;s:Body&#34; =         {
      &#34;m:GetItemResponse&#34; =             {
            &#34;m:ResponseMessages&#34; =               {
                &#34;m:GetItemResponseMessage&#34; =                     {
                  ResponseClass = Error;
                  &#34;m:DescriptiveLinkKey&#34; =                         {
                        text = 0;
                  };
                  &#34;m:Items&#34; =                         {
                  };
                  &#34;m:MessageText&#34; =                         {
                        text = &#34;An internal server error occurred. The operation failed., Cannot open mailbox /o=First Organization/ou=Exchange Administrative Group(FYDIBOHF23SPDLT)/cn=Recipients/cn=00037FFEE6F0D3D2.&#34;;
                  };
                  &#34;m:MessageXml&#34; =                         {
                        &#34;t:Value&#34; =                           (
                                                            {
                              Name = InnerErrorMessageText;
                              text = &#34;Too many concurrent connections opened.&#34;;
                            },
                                                            {
                              Name = InnerErrorResponseCode;
                              text = ErrorTooManyObjectsOpened;
                            },
                                                            {
                              Name = InnerErrorDescriptiveLinkKey;
                              text = 0;
                            }
                        );
                  };
                  &#34;m:ResponseCode&#34; =                         {
                        text = ErrorInternalServerError;
                  };
                };
            };
            &#34;xmlns:m&#34; = &#34;http://schemas.microsoft.com/exchange/services/2006/messages&#34;;
            &#34;xmlns:t&#34; = &#34;http://schemas.microsoft.com/exchange/services/2006/types&#34;;
      };
      &#34;xmlns:xsd&#34; = &#34;http://www.w3.org/2001/XMLSchema&#34;;
      &#34;xmlns:xsi&#34; = &#34;http://www.w3.org/2001/XMLSchema-instance&#34;;
    };
    &#34;s:Header&#34; =         {
      &#34;h:ServerVersionInfo&#34; =             {
            MajorBuildNumber = 1034;
            MajorVersion = 15;
            MinorBuildNumber = 11;
            MinorVersion = 1;
            xmlns = &#34;http://schemas.microsoft.com/exchange/services/2006/types&#34;;
            &#34;xmlns:h&#34; = &#34;http://schemas.microsoft.com/exchange/services/2006/types&#34;;
            &#34;xmlns:xsd&#34; = &#34;http://www.w3.org/2001/XMLSchema&#34;;
            &#34;xmlns:xsi&#34; = &#34;http://www.w3.org/2001/XMLSchema-instance&#34;;
      };
    };
    &#34;xmlns:s&#34; = &#34;http://schemas.xmlsoap.org/soap/envelope/&#34;;
};
</code></pre>

<p>显然问题是同时连接太多。</p>

<p>我的代码流程是:</p>

<p>我的 <code>HTTPRequest.m</code> 有一个方法</p>

<pre><code>- (void)fetchData
{
    dispatch_async(dispatch_get_main_queue(), ^{

      sessionAlive = sessionAlive + 1;

      NSLog(@&#34;sessionCount: %ld&#34;, (long)sessionAlive);

      NSURLSessionConfiguration *defaultConfiguration = ;

      NSURLSession *defaultSession = [NSURLSession sessionWithConfiguration:defaultConfiguration
                                                                     delegate:self
                                                               delegateQueue:nil];

      NSURLSessionDataTask *dataTask = ;

      ;
    });
}

// Some NSURLSession delegates methods here

-(void)URLSession:(NSURLSession *)session
   dataTask:(NSURLSessionDataTask *)dataTask
   didReceiveData:(NSData *)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 = ;
      }

      self.successBlock ? self.successBlock(self.redirectLocation, data) : nil;
    }

    ; // We must release the session, else it holds strong referance for it&#39;s delegate (in our case EWSHTTPRequest).
                                        // And it wont allow the delegate object to free -&gt; cause memory leak
}
</code></pre>

<p>我正在同时下载类似这样的电子邮件:</p>

<pre><code>dispatch_queue_t backgroundQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0);

dispatch_async(backgroundQueue, ^{

foreach (NSString *emailId in emalilIDArray)
    {
   HTTPRequest *request = init];
      ;
    }
});
</code></pre>

<p>我认为我的问题是我在每次通话时都在进行 session ,但我不知道看到其他方式。</p>

<p>如果我不能使用共享实例 session ,因为我需要将 session 的委托(delegate)与每个 HTTPRequest 对象关联以处理响应。</p>

<p>有什么建议或更好的方法吗?</p></p>
                                    <br><hr><h1><strong>Best Answer-推荐答案</ strong></h1><br>
                                            <p><p>为了尽量减少架构更改,我可能会建议使用单例来管理 session ,但代理对相关对象的委托(delegate)调用。换句话说:</p>

<ol>
<li>使用 <code>NSURLRequest</code> 调用该单例类的方法并让它创建任务;也将您的 <code>HTTPRequest</code> 对象传递给该方法,以便它知道该调用谁来处理结果。</li>
<li>在单例类中,将新创建的 <code>NSURLSessionTask</code> 对象作为键存储在字典中。</li>
<li>将您的 <code>HTTPRequest</code> 对象存储为相应的值。</li>
<li>编写一大堆每个任务的委托(delegate)方法,每个方法在字典中查找任务并在正确的 <code>HTTPRequest</code> 对象上调用相同的委托(delegate)方法。</li>
<li>任务完成后,将其从字典中移除以释放 <code>HTTPRequest</code> 对象。</li>
</ol>

<p>或者,如果所有 <code>HTTPRequest</code> 对象确实在做的是提供一堆身份验证处理方法并积累数据,您可以考虑创建一个接受 <code>NSURLRequest</code> 的单例类> 取而代之的是一个对象和一个 block ,并在您获取数据时运行该 block 。</p>

<p>就此而言,如果您不以增量方式处理数据,您也可以考虑将该 block 直接作为任务的 <code>completionHandler</code>block 传递,并让 session 本身处理数据累积。</p></p>
                                   
                                                <p style="font-size: 20px;">关于ios - NSURLSession 多个并发请求被 Exchange 服务器拒绝,我们在Stack Overflow上找到一个类似的问题:
                                                        <a href="https://stackoverflow.com/questions/43393131/" rel="noreferrer noopener nofollow" style="color: red;">
                                                                https://stackoverflow.com/questions/43393131/
                                                        </a>
                                                </p>
                                       
页: [1]
查看完整版本: ios - NSURLSession 多个并发请求被 Exchange 服务器拒绝