内容提要
文章辨析了IM与HTTP的差异:HTTP是一次性单向通讯,不适合即时通讯;Socket并非协议,而是连接应用层与传输层的接口库,以及存储IP、端口和连接状态的套接字。IM本质上是业务层通过Socket库调用TCP/UDP实现的双向长连接。心跳机制用于应对网络波动、NAT超时和防火墙断连,可及时重连、清理资源并维持链路活跃。
延伸解读
HTTP 并非不能做即时通讯,但代价明显
文章指出 HTTP 是一次性通讯,请求返回后连接即关闭,服务端无法主动推送。若用轮询实现即时通讯,客户端需每隔几秒请求一次,在用户量大的场景下显然不适合。不过作者也说明,HTTP/1.1 开启 keep-alive 或 HTTP/2.0 不关闭套接字时,理论上也能实现双向通讯,只是实际中很少这样用。
Socket 不是协议,理解这一点很关键
很多人误以为 Socket 是协议,但文章强调根本不存在 Socket 协议。Socket 实际有两个身份:一是连接应用层与传输层的接口库,提供 connect、read、write 等调用;二是存储 IP、端口及连接状态的套接字。把 Socket 理解为“中间件”更准确,它既帮应用层对接传输层,也为数据传输提供信息判断能力。
心跳不只是保活,更是服务端高可用的手段
文章将心跳的必要性归结为维系长连接、保持高可用。移动网络波动、NAT 超时、防火墙定时关闭连接都会导致套接字失效。心跳能让客户端尽快重连,让服务端及时感知连接变化并清理 Socket 资源,同时用数据包告知中间设备连接仍活跃。若缺少心跳,连接中断可能无法被及时发现。
TCP Keepalive 有盲区,应用层心跳不可替代
TCP 自带 Keepalive,默认关闭,且默认每 2 小时才发送一次,只能判断内核层是否响应,无法感知业务层是否崩溃。因此文章建议将 TCP Keepalive 与应用层心跳配合使用:前者判断网络通路是否正常,后者判断业务服务器是否可用。智能心跳则可根据网络环境动态调整频率,平衡 NAT 超时与电量、流量消耗。
Q&A
IM 和 HTTP 在通讯方式上有什么本质区别?
HTTP 是一次性单向通讯,请求返回后连接关闭,终端和服务端感知不到对方存在;而 IM 需要双向长连接,服务端能主动推送消息并感知连接状态。
Socket 到底是什么?它是协议吗?
Socket 不是协议。它有两个身份:一是 Socket 库,提供 write、read、connect 等接口,连接应用层和传输层;二是 Socket 套接字,存储 IP、端口和连接状态等信息。
为什么说 HTTP 不适合大量用户下的即时通讯?
HTTP 请求返回后即关闭连接,服务端无法主动推送消息,也无法及时感知终端连接中断以清理资源。若用轮询实现即时通讯,在大量用户场景下效率低下。
IM 的本质是什么?它是如何实现的?
IM 本质是业务层通过 Socket 库调用 TCP/UDP 等传输层协议,利用 Socket 套接字确定对方 IP 和端口,实现双向长连接消息收发。
心跳机制在 IM 中解决什么问题?
心跳用于维系长连接、保持高可用,应对网络波动、NAT 超时和防火墙断连等问题,使客户端及时重连、服务端清理资源,并告知中间设备连接活跃。
TCP Keepalive 和应用层心跳有什么区别?应该如何选择?
TCP Keepalive 在传输层发送心跳,只能判断网络是否正常,无法感知业务层崩溃;应用层心跳可判断业务服务器状态。两者配合使用可兼顾网络与业务检测。