网络监听
蜂窝无线系统(LTE、4G、3G 等)对电量的消耗远大于 WiFi 信号。根源在于 LTE 设备 基于多输入、多输出技术,使用多个并发信号以维护两端的 LTE 链接。
应该避免在没有连接WIFI的情况下进行高带宽消耗操作,因此,我们需要
- 在进行任何网络操作之前,先检查网络的连接是否可用
- 持续监视网络的可用性,并在连接状态变化时给予适当反馈
苹果公司提供了示例代码(http://apple.co/1Q3gRKL),以检查和监听网络状态的变化。如 果 你 的 项 目 使 用 了 CocoaPods, 那 么 请 使 用 Tony Million 的 Reachabilitypod(https:// github.com/tonymillion/Reachability)。
网络请求过程
正常一条网络请求需要经过的流程是这样:
1.DNS 解析,请求DNS服务器,获取域名对应的 IP 地址。
2.与服务端建立连接,包括 tcp 三次握手,安全协议同步流程。
3.连接建立完成,发送和接收数据,解码数据。
DNS查找
发起连接的第一步是 DNS 查找。如果你的应用严重依赖网络操作,DNS 的查找时间会使应用变慢。
为了最大限度地减少 DNS 查询时间所产生的延迟,你应该遵循以下的最佳实践。
• 最小化应用使用的专有域名的数量。按照路由的一般工作方式,多个域名是不可避免的。
最好是能做到以下几点:
(1) 身份管理(登录、注销、配置文件) (2) 数据服务(API 端点)
(3) CDN(图片和其他静态人工产品)
有可能需要其他域名(例如,用于提供视频、上传检测数据、具体的子数据服务、广告 投放,甚至是国家特定的全球本地化)。如果子域名数量上升至两位数,那么势必会引 发担忧。
• 在应用启动时不需要连接所有的域名,可能只需要身份管理和初始画面所需的数据。对 于后续的子域名,尝试更早地进行 DNS 解析,也被称为 DNS 预先下载。为实现此操作, 你可以参考以下两点。
如果子域名和主机在控制范围内,你可以配置一个预设的 URL,不返回任何数据,只 返回 HTTP 204 的状态码,然后提前对该 URL 发起连接。
第二个方法是使用 gethostbyname 执行一个明确的 DNS 查找。然而,针对不同的协议, 主机可能会解析至不同的 IP,例如,HTTP 请求可能会解析至一个地址,而 HTTPS 会 解析至另一个地址。虽然不是很常见,但第 7 层的路由可以根据实际的请求解析 IP 地 址,例如,图像是一个地址,视频是另外一个地址。鉴于这些因素,在连接之前解析 DNS 经常是无用的,对主机进行伪连接会更有效。
SSL握手时间
为了安全起见,可以假设应用中所有的连接均是通过 TLS/SSL 的(使用 HTTPS)。HTTPS在连接开始时,先进行 SSL 握手,SSL 握手主要是验证服务器证书,同时共享用于通信的 随机密钥。这一操作听起来简单,但是却有很多步骤,还会耗费较多时间(见图 7-3)。
你应该遵循以下的最佳实践。
最大程度地减少应用发起的连接数。因此,也需要减少应用连接的独有域名的数量
请求结束后不要关闭 HTTP/S 连接。
为所有的HTTPS请求添加头Connection: keep-alive。这确保了同样的连接在下一次 请求时可以复用。使用域分片。如此一来,虽然连接的是不同的主机名,你也可以使用同一个 socket,只 要它们解析为相同的 IP,可以使用相同的证书(例如,在通配符域)就行了。 域分片在 SPDY 及其后续版本——HTTP/2(https://http2.github.io)——中是可用的。你 需要一个支持上述任意一种格式的网络库。