AFHTTPSessionManager的创建方式对网络连接的影响

1,759 阅读3分钟

我们都知道:

  • TCP的四元组

    源IP, 目标IP, 源端口, 目标端口

  • HTTP默认端口80, HTTPS默认端口443

  • AFHTTPSessionManager继承自AFURLSessionManager, 封装了常用的HTTP方法

查看相关文档

AFN的AFHTTPSessionManager

WechatIMG3800.png

可以看到如果NSURLSessionConfiguration是background session的话, 那么AFHTTPSessionManager就必须是全局的

WechatIMG3801.png

销毁session的方法

WechatIMG3802.png

manager类方法

WechatIMG3797.jpeg

可以看到这里不是单例模式

NSURLSession的HTTPMaximumConnectionsPerHost

WechatIMG3804.png

同一个session同一个host, iOS系统的TCP最大连接数默认是4

可以修改配置

WechatIMG3805.png

抓包测试AFHTTPSessionManager的创建方式对网络连接的影响

使用Wireshark + Charles + 真机, 过滤下IP

观察端口列, 几张图的第一行高亮均为上一次请求的结束, 然后刷新接口

AFHTTPSessionManager非单例:

WechatIMG3793.png

可以看到客户端的端口由50847新增了50848, 紧接着TCP三次握手

WechatIMG3794.png

这次刷新了三个接口, 可以看到客户端的端口多了50866, 50867和50868, 紧接着都是TCP三次握手

这里的连接并不是每次请求结束就FIN的, 是过一段时间FIN或RST的

AFHTTPSessionManager单例:

WechatIMG3791.png

WechatIMG3792.png

请求同样的几个接口, 可以看到客户端的端口是同一个50735, 没有新增

HTTP1.1的Connection默认是keep-alive, 多个请求可以共用一个TCP连接

HTTP2实现了多路复用, 使用一个连接可以并行发送多个请求和响应, 真·全双工

如果每次请求都新建session, 新建TCP连接, 属实有些违背了HTTP1.1或HTTP2

HTTP的版本是如何选择的

先看应用启动的第一个接口

WechatIMG3831.png

1 表示当前协议版本

2 ALPN 应用层协议协商(Application-Layer Protocol Negotiation)是一个传输层安全协议(TLS) 的扩展, ALPN 使得应用层可以协商在安全连接层之上使用什么协议, 避免了额外的往返通讯, 并且独立于应用层协议. 可以看到Client支持的有HTTP1.1和HTTP2, 而Server选择了HTTP2, 那么ALPN是什么时候传输的呢, 查看TLS的Client Hello里发现了这个扩展, 而在Server Hello里回应了选择的版本, 二者如下图

WechatIMG3834.png

WechatIMG3833.png

3 Client Address和Remote Address, 各自的IP和端口, 对应了TCP的四元组

4 TLS的握手流量

可以根据3和4来判断TCP连接是否复用, 在相同域名且不切换网络的情况下一般多个TCP连接里也就Client的端口号会变化

再看一下后面再次对这个接口的请求

WechatIMG3830.png

Client的端口号未改变且没有TLS的过程, 可知连接复用了, 既节省了连接时间, 而且同一个接口的流量从1757字节降低到346字节

可见连接共用的好处还是很大的, 所以我们的代码也要尽可能支持

iOS下如何支持

iOS9开始NSURLSession支持HTTP2, AFN3.0就可以啦, 所以客户端不需要什么额外的操作, 后端的框架一般也会支持

封装session单例时可以将acceptableContentTypes封在里面, 因为一般都不会变, 而像可能有变动需求的配置如timeoutInterval就可以获取到单例对象后再设置, 甚至对于不同的securityPolicy创建多个session单例都可以, 总之, 可以根据业务需求灵活的配置

官方文档

官方对多session的创建是期望对task的不同配置

WechatIMG3806.jpeg