【发布时间】:2016-03-23 06:04:45
【问题描述】:
我遇到了NSURLConnection 的问题,我暂时无法解决。
我向服务器发出请求,但处理数据需要很长时间(平均大约 7 分钟)。所以客户端需要等待响应,因此我尝试通过在NSURLRequest 中设置很长时间来保持 HTTP 连接打开。我现在不想诉诸基于轮询的解决方案。
请求代码:
- (void)sendNextExample
{
url = ...
json = ...
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url
cachePolicy:NSURLRequestReloadIgnoringCacheData
timeoutInterval:600.0];
[request setHTTPMethod:@"POST"];
[request setHTTPBody:json];
NSURLConnection *newConnection = [[NSURLConnection alloc] initWithRequest:request
delegate:self
startImmediately:NO];
if (!queue)
{
queue = [NSOperationQueue new];
}
[newConnection setDelegateQueue:queue];
self.connectionStatus = @{@"index" : @(i), @"data" : [NSMutableData data]};
[newConnection start];
}
处理代码(简化):
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
NSMutableData *buffer = self.connectionStatus[@"data"];
[buffer appendData:data];
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
// log and interrupt process
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
// do sth with buffer data
// finalize
}
问题是,我从来没有收到来自服务器的任何东西并且连接超时(在 600 秒 = 10 分钟之后,如 NSURLRequest 中所定义),即使该过程似乎在服务器端。在连接超时之前,任何时候都不会调用任何委托方法。
为了验证服务器进程并将数据正确返回给客户端,我通过使用 curl 从完全相同的客户端向完全相同的服务器执行多个请求来进行测试:
curl -H "Content-Type: application/json" -X POST -d '{"foo":0.0, "bar":1.0}' serveraddress:8000
这些请求似乎按预期工作,即上述请求在 7 分钟后返回正确的数据:
{"bar":0.5, "baz":10.0} // expected data
因此,我怀疑罪魁祸首在于NSURLConnection,所有其他事情都是一样的。
下一步,我使用不同持续时间的服务器端进程执行了多个请求,发现NSURLConnection 在请求后大约 5 分钟后开始忽略响应。
所以问题自然是,有没有人经历过这种情况?这种行为是否正常/预期?
是否有任何理由(甚至可能是操作系统调解)NSURLConnection 会忽略一定时间后收到的数据,即使在请求中正确设置了超时?任何可能导致此问题的细则或未记录的“功能”?
最终,是否会切换到 NSURLConnection 以外的其他东西,例如 AFNetworking,让我有机会绕过这个明显的“限制”?
(当然,如果有任何关于如何执行以其他方式描述的任务的建议,他们也会非常欢迎!)
为了清楚起见,客户端是 Yosemite 机器(Xcode 7),而服务器使用 .Net 4.5(Windows 8 机器)中的HttpListener 编写。该服务器已经在其他场合进行了测试,并按预期工作。
编辑:这个问题发布半年多后,问题依然存在。我设法通过从可可调用 curl 来完成我的工作(不优雅,但工作),因此无数次验证罪魁祸首确实在于NSURLConnection。我终于得出结论,这是一个错误,并将发布它(如果我有时间这样做),但老实说,我并没有抱太大希望。
EDIT2:轮询显然是这里的另一种选择。但是,我不能使用轮询,因为我的一些请求需要非常快地返回( 1 分钟)。使用轮询意味着增加请求/响应所需的最短时间。
【问题讨论】:
标签: objective-c cocoa http timeout nsurlconnection