iOS 和 Go - Keep-Alive 使用 NSURLSession

iOS and Go - Keep-Alive using NSURLSession

在我的 iOS 应用程序中,我有一个从服务器获取结果的搜索功能。搜索会随着用户更新查询而实时更新,因此这会导致连续发出多个请求。

所以我的问题是,如何确保在这些连接上使用 TCP keep-alive?我想尽可能减少延迟,因此在第一个请求后保持连接并重新用于后续请求非常重要。

我正在使用 NSURLSession,我听说它默认使用 keep-alive,但我如何才能确定呢?在服务器上记录请求显示每个连续请求之间没有区别,但我不希望仅从 header 信息中看到任何变化。

这里有什么帮助吗?我在我的服务器上使用 Go,所以它可能也需要一些额外的配置。

我认为您将 TCP keep-alive 与 HTTP keep-alive(持久连接)混淆了。这些是不相关的概念。根据您的问题,您可能指的是 HTTP 持久连接。

在 HTTP/1.1 中,持久连接是默认设置,并且被 NSURLSession 和几乎每个 HTTP/1.1 客户端使用。你必须要求关闭它们。您可以检查 HTTP header 中的 Connection: close,或者在服务器端,您可以检查 http.RequestClose 字段。但我确定您会获得持久连接。这意味着您不必为每个请求重新协商 TLS 隧道(或至少 TCP three-way 握手)。 (虽然如果你进行并行请求,仍然会有多个连接你必须协商。HTTP/1.1 一次只能处理一件事,而 NSURLSession 会尝试使用连接池以缩短响应时间。)

TCP keep-alives 是完全不同的东西。它会定期向另一端发送 "ping" 以确保它仍然可以访问。有很多方法可以让您失去网络连接,并且直到您下次尝试通信时才知道,正常的症状是连接挂起,您需要将其超时。理论上 TCP keep-alive 只是发现这一点的工具,但我几乎从未发现它实用。很难正确配置(尤其是在 Cocoa 中)。您几乎总是需要为您的应用程序构建 higher-level "ping" 功能,而不是依赖于此。

但将其带回您的问题,HTTP/1.1 可能对您来说还不错 as-is,但您需要仔细管理您的回复。如果您对每封信都提出新的请求并发回大量回复,那么效果会很差。您将使所有连接池忙于下载您要丢弃的东西。您需要首先关注好的算法。至少,您可能只想一次发送几个结果,并在 API 中提供一个 "paging" 方法来为同一搜索请求更多结果。

要确定 TCP 正在做什么,您可以启用 CFNETWORK_DIAGNOSTICS。来自文档:

During normal development you can set this environment variable via Xcode's scheme editor. If you need to investigate problems outside of Xcode, you can set it programmatically using the code shown in Listing 1.

Listing 1 Programmatically enabling CFNetwork diagnostic logging

setenv("CFNETWORK_DIAGNOSTICS", "3", 1);

You should do this right at the beginning of the app's launch sequence. Normally putting this at the start of main is sufficient, but if you have C++ static initialisers that use CFNetwork you'll have to run it before them.

CFNetwork diagnostic logging starts up when you first use CFNetwork—or any framework, like Foundation, that uses CFNetwork—at which point it will print a message like that shown in Listing 2.

Listing 2 An example of the CFNetwork diagnostic logging startup message

2014-10-28 14:23:37.115 QTestbed[2626:60b] CFNetwork diagnostics log file created at: /private/var/mobile/Applications/76531F40-3291-4565-8C75-0438052C83BC/Library/Logs/CrashReporter/CFNetwork_com.example.apple-samplecode.QTestbed_2626.nwlrb