我的iOS应用从nginx HTTP服务器加载图片。发送400多个此类请求后,网络“卡住”,所有后续HTTP请求都会导致“请求超时”错误。只有在我重新启动应用程序时,我才能再次加载图像。
详细信息:
NSURLSession.sharedSession().dataTaskWithURL
向jpeg文件发送400个HTTP GET请求。cancel()
对象的NSURLSessionDataTask
方法取消之前的每个未完成请求。有趣的是:
问题的原因是什么?任何人都可以推荐其他方法或工具来分析和调试它吗?
这个演示应用程序100%的时间为我重现了这个问题。
https://github.com/exchangegroup/ImageLoadDemo
我的nginx配置:http://pastebin.com/pYYjdxfP
OS X :10.10.4(14E46), iOS :8和9, Xcode :7.0(7A218), nginx :1.9.4
只有在为每个请求创建新的NSURLSession并使用finishTasksAndInvalidate
或invalidateAndCancel
清除上一个会话时,我才设法保持请求有效。
// Request 1
let configuration = NSURLSessionConfiguration.defaultSessionConfiguration()
let session = NSURLSession(configuration: configuration)
session.dataTaskWithURL ...
// Request 2
// clear the previous request
session.finishTasksAndInvalidate()
let session2 = NSURLSession(configuration: configuration)
session2.dataTaskWithURL ...
答案 0 :(得分:1)
一种可能性是iOS开始发送请求,然后数据包丢失阻止了标头和请求主体完全交付。
另一种可能的想法是,您的服务器可能没有记录请求,直到它实际完成尝试传递它,这会使服务器日志中的时间戳与连接关闭时的时间戳对齐,而不是在它被打开了。 (IIRC,这就是Apache所做的;我还没有和nginx一起工作,所以我不能说它的行为。)如果是这样,那么这只是一个简单的连接失速。至于它为何停滞不前,我无法猜测。
问题是否仅针对HTTPS流量发生?如果你可以用HTTP重现它,你就不需要Charles Proxy;只需使用OS X"互联网共享"功能,并使用tcpdump或wireshark捕获数据包,在网桥接口上侦听。如果您无法使用HTTP重现它,那么在验证服务器证书时,我的钱将会出现获取CRL或执行OCSP检查的问题。
由于过度异步调度到新队列,您的应用程序是否会以大量线程结束?因为这很容易引起各种奇怪的不端行为。
超时有多长?如果它太短,您的应用程序可能只是在遇到硬件的性能限制时运行,同时处理仅在四秒内发送的400个请求的结果。
另外,您是否尝试同时安排这些请求?因为我似乎记得如果你在同一时间在一个会话中启动太多任务,那么就会读到一个导致NSURLSession碰到砖墙的错误。您可以尝试仅在会话中的任务数量低于某个阈值后添加任务,并查看是否可以解决问题。