最近我一直在解决一个HTTP超时问题。经过一个多月的调查,我相当确定它是由于不良的HTTP持久连接引起的。详情如下:
- 这是一个iOS应用程序。
- 大多数用户正在运行iOS 8。
- 我正在使用
NSURLConnection
。 - iOS 8有一个已知的
keep alive
bug,但我的问题是另一个问题。更具体地说,该bug会导致NSURLErrorNetworkConnectionLost
,但我的错误是NSURLErrorTimedOut
。然而,我不确定我的问题是否是由iOS 8的另一个bug引起的。 - 我的问题行为:在使用一段时间后 - 在成功发送一些HTTP请求并接收到对应的响应之后 - 一个请求将导致
NSURLErrorTimedOut
,而所有随后的(与最后一个请求时间不太远以便重用持久连接)请求都将导致NSURLErrorTimedOut
。 - 一些可行的解决方法:
- 杀死并重新启动应用程序。
- 关闭iPhone上的WiFi连接以强制使用3G/4G。
- 打开空中模式,然后关闭它。
- 我的分析:从行为来看,问题似乎是由一个坏掉的持久连接引起的。所有后续请求都会继续使用此持久连接,所以都会失败并显示
NSURLErrorTimedOut
。从可行性解决方法可以看出,它们都能正常工作,因为它们导致了坏的持久连接被丢弃并创建了新的持久连接。
我的问题是:
- 还有人遇到过这个问题吗?
- 这是iOS 8的已知bug吗?
- 它是由服务器的某些不同寻常的配置引起的吗?我无法控制服务器,但我知道它们使用nginx 1.6.1,并且他们的工程师正在与我一起调查此问题。我应该向他们询问哪些信息?
- 是否有办法强制
NSURLConnection
不重用当前的持久连接,而是创建一个新的持久连接,以便在检测到问题后我可以解决此问题?
更新:
通过使用CFNetwork
并直接控制Connection
头,我成功地缓解了这个iOS 8上的问题。然而,它似乎在iOS 9上变得更糟。
由于我对苹果将在iOS 9上解决这个问题的希望已经破灭,所以最终我发了一个radar:http://www.openradar.me/22770738。
如果您也遇到此问题,请复制我的radar,甚至最好是,如果您拥有更可靠的可重现示例,请发出自己的radar。
connection
头设置为close
,但不幸的是,使用NSMutableURLRequest
是不可能的。 - an0