什么是心跳?
简单来说,心跳就是用来检测TCP连接的双方是否可用.虽然TCP的KeepAlive机制只能保证连接的存在,但是并不能保证客户端以及服务端的可用性. 如果某台服务器因为某些原因导致负载超高, CPU100%,无法响应任何业务请求,但是使用TCP探针则仍旧能确定连接状态,这就是典型的链接活着但是业务方已死.
这时候心跳机制就起作用了:
我们客户端发起心跳Ping(一般都是客户端), 假如设置10秒后如果没有收到回调,那么说明服务器或者客户端某一方出现问题,这时候我们需要主动断开连接.
服务端也是一样,会维护一个socket的心跳间隔,当约定时间内,没有收到客户端发来的心跳,我们会知道该连接已经失效,然后主动断开连接.
其实我们真正需要心跳机制的原因主要是在于国内运营商NAT超时
什么是NAT超时?
是ipv4引起的,我们上网可能处于一个NAT设备(无线路由器之类),会修改Ip,TCP/UDP协议的端口号,能让内网中的设备共用同一个外网IP.没多接一次路由器,我们发出的数据包会多经过一次NAT
国内移动无线网络运营商在链路上一段时间内没有数据通讯后,会淘汰NAT表中的对应项,造成链路中断.
国内的运营商一般NAT超时时间5分钟,所以我们心跳设置时间间隔为3-5分钟.
PingPong机制
如果我们在地铁电梯类似无网环境下,那么我们岂不是无法保证消息的即时性?业内解决方案是采用双向的PingPong机制.
当服务器发出一个Ping,客户端没有在约定的时间内返回响应的ack,则认为客户端已经不在线, 这是我们Server会主动断开Scoket连接,改为APNS推送的方式发送消息.
同样的,当客户端去发送一个消息, 因为我们迟迟无法收到服务器的响应ack包,则表明客户端或服务端已不在线,我们也会显示消息发送失败,并断开scoket连接.
重连机制:
理论上,我们自己主动去断开Scoket连接(如退出账号,APP退出到后台等),不需要重连.其他的连接断开,我们都需要进行断线重连.一般解决方案是尝试重连几次,如果仍旧无法重连成功,那么不再重连.
有关基于底层OS 的Socket实现的简单的用到socket(), sockaddr_in, connect(),close()几个方法
基于CocoaAsyncSocket框架实现一个简单IM.CocoaAsyncSocket是基于Socket,这个框架实现了两种传输协议TCP和UDP,分别对应GCDAsyncSocket/GCDAsyncUdpSocket,同样是基于原生的Scoket的框架.
基于webScoket的简单IM例子