如何在 NSURLSession 中禁用每个套接字的多个请求?

How to disable multiple requests per socket in NSURLSession?

我正在进行批量上传并使用 NSURLSession 在后台进行。 直到 iOS9 一切顺利,但 iOS10 有不同的行为:

如果我 queue 100 POST 个请求,它将把它们全部批处理到同一个套接字.

因此所有 100 个请求都在同一个套接字上并行发生,并在几分钟后超时。

在服务器端,我们使用的是 AWS ELB,我猜我可以通过请求 headers / ELB 设置禁用此行为。服务器本身是 node.js。建议?

编辑:

Http header Connection: keep-alive 可能是这样。 但我无法更改它,我看到它使用 Charles 代理从 close 覆盖回 keep-alive

理论上?或者:

  • 使用多个会话。 NSURLSession 不跨会话边界共享连接。
  • 使用外部队列(例如 NSOperationQueue)来限制添加到单个会话的并发请求数。

对于后台上传,可能唯一的选择是第一个。请注意,您应该 将每个请求发送到一个单独的会话,因为您最终会从 TLS 协商等中得到很多不必要的开销。只需将每个会话的请求数保持在一定范围内理智。

但是,我怀疑这些方法中的任何一种对您有帮助。无论是一个插座还是十个插座,您遇到的问题是蜂窝网络无法长时间可靠地保持连接打开,或者亚马逊的 servers/routers 不愿意这样做。

所以真正的修复几乎肯定涉及正确的重试逻辑。

但是当你说 "in parallel on the same socket" 时我有点困惑。这是不可能的,除非启用了 HTTP 流水线,据我所知,默认情况下它不是,即使在 iOS 10 中也是如此。确保你没有错误地打开它。

最终我们使用 http header Connection.

解决了这个问题

iOS 使用其 Keep-Alive 选项,这意味着您可以在同一个套接字上发送多个请求。关闭流水线或设置 header 值都不能将其删除。 iOS 强制它。 所以我们最终从服务器的响应中删除了它。它导致 iOS 每个请求打开一个新套接字。

这样我们就得到了与 NSURLSession 号匹配的连接号。允许我们在 iOS 10 和 11 的测试版中在后台上传一堆大文件。