关于WebSocket心跳的理解
Posted 敲代码的小小酥
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了关于WebSocket心跳的理解相关的知识,希望对你有一定的参考价值。
首先,WebSocket是基于TCP连接的,TCP连接有keepalive机制,检测双方是否正常,但是keepalive有一定的局限性:
1.client异常挂死,此时keepalive机制无法反馈真实的client状态; 2.client 异常断电断网出现TCP假死keepalive并不能根本性解决问题,实际上互联网环境很不稳定;3.ws在应用层,基于传输层,在ws中操作TCP也很不方便。封装就意味着易用性提高灵活性降低。
在另一篇文章中,找到了下面一段通俗易懂的话,也是为何TCP的keepalive不行的原因:
如果正在通信,忽然一端异常掉线了 – 比如断电了什么的,这种tcp是能很快的知道对方掉线的,因为tcp有应答,就算只有一方发送,那也会有双向的通信,可以保证链路是通的,且对方在线。
但是,如果链路上没有数据正在发送,那tcp就搞不清楚对方是否在线了,你们之间的链路,是虚拟的,所以如果完全没有数据传输,tcp也搞不定这个事情。
回过来说,发送ping/pong,其实就是在链路上跑个数据,这样tcp就能搞清楚有没有掉线,没掉线更好,掉线了就能很快的响应过来
所以,既然有一方发送了数据,tcp知道了,不就行了吗?为啥还要回复一下,不是浪费么,,,但是tcp是还是tcp,上层协议可就一定还是websocket了,比如ws断开后,tcp被快速的占用了,,,所以有了ping,还得有pong
keepalive的特性,我们后面再说,这里只要知道,使用TCP的keepalive机制,是有问题的,所以,最好自己实现WebSocket的心跳机制。
作为浏览器客户端而言,大部分浏览器已经实现了WebSocket的心跳机制,所以,只要WebSocket的服务端发送了Ping消息,浏览器客户端会自动回复Pong消息,而且服务端如果不发送ping,在连接一段时间后,浏览器会自动断开连接,这些功能无需程序员手动实现。但是服务端需要手动发送Ping消息,还要判断是否收到pong消息,来判断浏览器客户端的存活状态。
而如果我们自己去实现WebSocket客户端的话,就需要手动实现pong的回复了。也需要判断是否定时收到ping的消息了。手动实现的好处就是在发送ping/pong的同时,可以携带一些其他的数据,来进行处理。
通常使用的tomcat-websocket,spring-websocket,都封装了pingmessage对象和pongmessage对象,我们可以直接用这些对象进行消息的发送。
以上是关于关于WebSocket心跳的理解的主要内容,如果未能解决你的问题,请参考以下文章