当网络通信采用tcp协议时,在真正的读写操作之前,sever与client之间必须建立一个连接,当读写操作完成之后,对方不再需要这个连接时他们可以释放这个链接,连接的连接需要三次握手,释放需要四次握手,也就是说每个连接的建立都是需要消耗资源和时间的
模拟一种TCP短连接的情况:
一般都是 client 先发起 close 操作。当然也不排除有特殊的情况。
从上面的描述看,短连接一般只会在 client/server 间传递一次读写操作!
短连接的操作步骤是:
优缺点:
应用场景:
长连接的操作步骤是:
保持连接用到了TCP保活功能
优缺点:
应用场景:
短连接环境下,数据交互完毕后,会主动释放连接;如果使用的是长连接的情况下,如果双方已经建立起了连接,但是很长一段时间内没有数据交换,而客户端可能意外断电、死机、崩溃、重启,还是中间路由网络无故断开,这些TCP连接没来得及正常释放,那么,因为服务端不知道客户端的情况,他就会一直维护这个连接,长时间的积累会导致非常多的半打开连接,造成服务端系统资源的消耗和浪费。所以服务端要做到快速感知失败,减少无效连接操作,这就有了TCP的Keepalive(保活探测)机制。
在长连接的情况下,双方的所有通信 都建立在1条长连接上(1次TCP连接);所以,长连接 需要 持续保持双方连接 才可使得双方持续通信
可是,长连接会存在断开的情况,而 断开原因 主要是
当进程被杀死后,长连接也会随之断开
当移动客户端网络状态发生变化时(如移动网络 & Wifi切换、断开、重连),也会使长连接断开
如网络状态差、DHCP的租期到期等等,都会使得长连接发生 偶然的断开
DHCP
的租期到期:对于Android
系统,DHCP
到了租期后不会主动续约 & 继续使用过期IP,
,从而导致长连接 断开
在了解长连接断开原因后,针对对应原因,此处给出 高效维持长连接的解决方案
为此,若需有效维持长连接,则需要做到
其实,说得简单点:高效维持长连接的关键在于
这是本文的重点,下节开始会详细解析
原理
检测网络状态变化 & 判断连接的有效性
具体实现
前者请参考文章:Android:检测网络状态&监听网络变化;后者主要存在于心跳保活机制,所以下面会在心跳保活机制中一起讲解。
对国、内外主流的移动IM产品(WhatsApp、Line、微信)进行了心跳机制的简单分析 & 对比,具体请看下图
下面,将根据市面上主流的心跳机制,设计 一套心跳机制方案
在下面的方案设计中,将针对这3个问题给出详细的解决方案。
为了减少流量 & 提高发送效率,需要精简心跳包的设计
设计原则
主要从心跳包的内容 & 大小入手,设计原则具体如下
设计方案
心跳包 = 1个携带少量信息 & 大小在10字节内的信息包
为了 防止NAT
超时 & 减少设备资源的消耗(网络流量、电量、CPU
等等),心跳发送的间隔时间 是 整个 心跳机制方案设计的重点。
设计方案
最直接 & 常用方案
一般,最直接 & 常用的心跳发送间隔时间设置方案 :每隔估计 x 分钟发送心跳包1次
其中,x <5分钟即可。(综合主流移动IM产品,此处建议 x= 4分钟)