WebSocket的状态检测可靠性
参考: IM系统的即时性和可靠性 Server-Sent Events 教程
一、WebSocket(包含socket io) 是否能随着以下行为,检测到连接状态改变【自测和网上找到的结果】
(一)客户端
- 断网能感知
- 服务器重启,能感知
- 关闭网页,能感知
- 链路中间的网络设备出现问题,连接实际上断开了,但客户端和服务器均无感知【网上说法】
- 用电脑管家,将浏览器设置断网,客户端无感知
(二)服务端
- 断网无感知
- 服务器重启
- 关闭网页,有感知
- 链路中间的网络设备出现问题,连接实际上断开了,但客户端和服务器均无感知【网上说法】
- 用电脑管家,将浏览器设置断网,服务端无感知
(三)总结
- 服务端与客户端,直接通过Api监听链接是否断掉,并不是可靠的【无法保证瞬时探知】,所以需要增加一个心跳检测机制;
- 如参考文章所言,心跳机制有以下优点:
总结:为什么基于TCP的websocket长连接仍然需要心跳机制
TCP连接的断开有时是无法瞬时探知的,因此不适合实时性高的场合 TCP协议的KeepAlive机制只能检测连接存活,而不能检测连接可用,【比如负载过高,虽连接存活,但是无法正常通信】 心跳机制能够避免连接被网络运营商回收
二、web客户端与服务器通讯的主要通信方式
- http
- http1.0 协议中,每次请求都会建立一次tcp连接,耗资源;
- http1.1 增加了长连接,默认使用,
Connection: keep-alive
,但需要携带完整header,并且只能客户端单项请求 - socket.io 框架默认在浏览器不支持websocket的时候,改为长轮询(Long-polling)
- 长轮询 客户端向服务端发送xhr请求,服务端接收并hold该请求,直到有新消息push到客户端,才会主动断开该连接。然后,客户端处理该response后再向服务端发起新的请求。以此类推。
- SSE(Server-Sent Events)
- 用于服务端向客户端推送消息
- 建立连接后,不会断开,客户端会一直等待接收服务端发过来的消息,但是只能由服务端向客户端发送
- WebSocket
- HTML5提出的通讯协议,基于TCP实现的可靠通信