【发布时间】:2017-05-19 19:52:42
【问题描述】:
我目前正在开发一个应用程序,我们需要一些请求来尽快访问我们的服务器。为了加快请求过程,我们必须消除握手(因为它需要额外的时间)并建立永久连接。
应用程序使用 Alamofire 框架向我们的服务器发出所有请求,设置如下:
我们有一个使用默认配置和 http 标头设置的会话管理器。
lazy var sessionManager: Alamofire.SessionManager = {
let configuration = URLSessionConfiguration.default
configuration.httpAdditionalHeaders = Alamofire.SessionManager.defaultHTTPHeaders
let manager = Alamofire.SessionManager(configuration: configuration)
return manager
}()
会话管理器在所有请求中都是持久的。每个请求都使用以下代码进行:
self.sessionManager.request(request.urlString, method: request.method, parameters: request.parameters)
.responseJSON { [weak self] response in
// Handle the response
}
request.urlString 是我们服务器“http://ourserver.com/example”的url
request.method 设置为 post
request.parameters 是一个参数字典
请求工作正常,我们得到了有效的响应。 问题出现在保活计时器上,我们的服务器将其设置为 300 秒。设备在 wifi 上最多保持连接 30 秒,并通过 GSM 几乎立即关闭。
服务器调试
我们在服务器上做了一些调试,发现如下结果
测试:
测试一:
- iPhone 通过 WiFi 连接到互联网
测试 2:
- iPhone 通过 3G 连接到互联网
行为:
- 两种情况:应用程序使用“Connection: keep-alive”向 Web 服务器发出 HTTP/1.1 请求;服务器(服务器 ip = 10.217.81.131)以“Keep-Alive: timeout=300, max=99”响应
- 客户端(测试 1 - WiFi 上的应用程序)在第 30 秒发送 TCP FIN 并关闭连接
- 客户端(测试 2 – 3G 上的应用程序)在收到来自其第一个 HTTP POST 的 HTTP/1.1 OK 消息后立即(零秒)发送 TCP FIN 请求
测试1在服务器端的日志:
在 23.139422,服务器响应 HTTP/1.1 200 OK 并使用“Connection: Keep-Alive”和“timeout=300”(300 秒)
往返时间 (RTT) 报告为 333.82 毫秒(这突出了我们在以下时间戳上的误差幅度):
在服务器端测试 2 日志:
应用程序立即关闭连接,其中立即是 21.197918 – 18.747780 = 2.450138 秒
在从 WiFi 切换到 3G 并返回时重复测试,并记录相同的结果。
客户端调试
使用 WiFi
第一次尝试(建立连接)
Optional(
[AnyHashable("Content-Type"): text/html,
AnyHashable("Content-Encoding"): gzip,
AnyHashable("Content-Length"): 36,
AnyHashable("Set-Cookie"): user_cookieuser_session=HXQuslXgivCRKd%2BJ6bkg5D%2B0pWhCAWkUPedUEGyZQ8%2Fl65UeFcsgebkF4tqZQYzVgp2gWgAQ3DwJA5dbXUCz4%2FnxIhUTVlTShIsUMeeK6Ej8YMlB11DAewHmkp%2Bd3Nr7hJFFQlld%2BD8Q2M46OMRGJ7joOzmvH3tXgQtRqR9gS2K1IpsdGupJ3DZ1AWBP5HwS41yqZraYsBtRrFnpGgK0CH9JrnsHhRmYpD40NmlZQ6DWtDt%2B8p6eg9jF0xE6k0Es4Q%2FNiAx9S9PkhII7CKPuBYfFi1Ijd7ILaCH5TXV3vipz0TmlADktC1OARPTYSwygN2r6bEsX15Un5WUhc2caCeuXnmd6xy8sbjVUDn72KELWzdmDTl6p5fRapHzFEfGEEg2LOEuwybmf2Nt6DHB6o6EA5vfJovh2obpp4HkIeAQ%3D; expires=Sun, 08-Jan-2017 12:51:43 GMT; path=/,
AnyHashable("Keep-Alive"): timeout=300, max=100,
AnyHashable("Connection"): Keep-Alive,
AnyHashable("X-Powered-By"): PHP/5.3.10-1ubuntu3.11,
AnyHashable("Server"): Apache/2.2.22 (Ubuntu),
AnyHashable("Vary"): Accept-Encoding,
AnyHashable("Date"): Sun, 08 Jan 2017 10:51:43 GMT])
第二次尝试(30 秒内,连接仍然有效)
Optional([AnyHashable("Content-Type"): text/html,
AnyHashable("Content-Encoding"): gzip,
AnyHashable("Content-Length"): 36,
AnyHashable("Keep-Alive"): timeout=300, max=99,
AnyHashable("Connection"): Keep-Alive,
AnyHashable("X-Powered-By"): PHP/5.3.10-1ubuntu3.11,
AnyHashable("Server"): Apache/2.2.22 (Ubuntu),
AnyHashable("Vary"): Accept-Encoding,
AnyHashable("Date"): Sun, 08 Jan 2017 11:00:18 GMT])
然后在 30 秒后连接断开 (FI)
使用 3G
第一次尝试
Optional([AnyHashable("Content-Type"): text/html,
AnyHashable("Content-Encoding"): gzip,
AnyHashable("Content-Length"): 36,
AnyHashable("Connection"): keep-alive,
AnyHashable("X-Powered-By"): PHP/5.3.10-1ubuntu3.11,
AnyHashable("Server"): Apache/2.2.22 (Ubuntu),
AnyHashable("Vary"): Accept-Encoding,
AnyHashable("Date"): Sun, 08 Jan 2017 11:04:31 GMT])
然后连接几乎立即断开。
【问题讨论】:
-
您是否还可以记录从服务器发送到您的应用程序的标头?请注意,某些代理可能会更改 keep-alive 标头。
-
您是否尝试过在客户端请求中使用“Keep-Alive”而不是“keep-alive”?规范有点模棱两可,但可能很重要。
-
@Sulthan 我在问题末尾的客户端调试下添加了从服务器进入应用程序的标头。我可以看到在 wifi 测试中保持活动有超时和最大值,而在 3g 测试中则没有。我想知道这是否是正常行为。
-
@zirinisp 这可能是您的运营商造成的。在 3G 上保持连接并不容易,因为您的 IP 可能经常变化。
-
@Sulthan 我们监控了 ip 更改,但我们没有。然而,连接正在断开。
标签: ios swift xcode alamofire nsurlsession