1. 心跳重连原由
![WebSocket心跳检测和重连机制](http://img.jiangsulong.com/220419/023004C47-0.jpg)
文章插图
心跳和重连的目的用一句话概括就是客户端和服务端保证彼此还活着,避免丢包发生 。
websocket连接断开有以下两种情况:
前端断开在使用websocket过程中,可能会出现网络断开的情况,比如信号不好,或者网络临时关闭,这时候websocket的连接已经断开,而不同浏览器有不同的机制,触发onclose的时机也不同,并不会理想执行websocket的onclose方法,我们无法知道是否断开连接,也就无法进行重连操作 。
后端断开如果后端因为一些情况需要断开ws,在可控情况下,会下发一个断连的消息通知,之后才会断开,我们便会重连 。如果因为一些异常断开了连接,我们是不会感应到的,所以如果我们发送了心跳一定时间之后,后端既没有返回心跳响应消息,前端又没有收到任何其他消息的话,我们就能断定后端主动断开了 。
因此需要一种机制来检测客户端和服务端是否处于正常连接的状态 。通过在指定时间间隔发送心跳包来保证连接正常,如果连接出现问题,就需要手动触发onclose事件,这时候便可进行重连操作 。因此websocket心跳重连就应运而生 。
2. 心跳重连的简单实现2.1 通过createWebSocket创建连接
function createWebSocket() {2.2 创建init方法,初始化一些监听事件,如果希望websocket连接一直保持, 我们会在close或者error上绑定重新连接方法 。
try {
ws = new WebSocket(wsUrl);
init();
} catch(e) {
console.log('catch');
reconnect(wsUrl);
}
}
function init() {2.3 重连操作,通过设置lockReconnect变量避免重复连接
ws.onclose = function () {
console.log('链接关闭');
reconnect(wsUrl);
};
ws.onerror = function() {
console.log('发生异常了');
reconnect(wsUrl);
};
ws.onopen = function () {
//心跳检测重置
heartCheck.start();
};
ws.onmessage = function (event) {
console.log('接收到消息');
//拿到任何消息都说明当前连接是正常的
heartCheck.start();
}
}
var lockReconnect = false;//避免重复连接2.4 心跳检测
function reconnect(url) {
if(lockReconnect) {
return;
};
lockReconnect = true;
//没连接上会一直重连,设置延迟避免请求过多
tt && clearTimeout(tt);
tt = setTimeout(function () {
createWebSocket(url);
lockReconnect = false;
}, 4000);
}
//心跳检测有的时候,客户端发送3次心跳包服务端均未回复才判定为失去连接,所以这时需要加上计数来判断 。
var heartCheck = {
timeout: 3000, //每隔三秒发送心跳
severTimeout: 5000, //服务端超时时间
timeoutObj: null,
serverTimeoutObj: null,
start: function(){
var _this = this;
this.timeoutObj && clearTimeout(this.timeoutObj);
this.serverTimeoutObj && clearTimeout(this.serverTimeoutObj);
this.timeoutObj = setTimeout(function(){
//这里发送一个心跳,后端收到后,返回一个心跳消息,
//onmessage拿到返回的心跳就说明连接正常
ws.send("123456789"); // 心跳包
//计算答复的超时时间
_this.serverTimeoutObj = setTimeout(function() {
ws.close();
}, _this.severTimeout);
}, this.timeout)
}
}
【WebSocket心跳检测和重连机制】//心跳检测最后总结下
var heartCheck = {
timeout: 3000, //每隔三秒发送心跳
num: 3, //3次心跳均未响应重连
timeoutObj: null,
serverTimeoutObj: null,
start: function(){
var _this = this;
var _num = this.num;
this.timeoutObj && clearTimeout(this.timeoutObj);
this.serverTimeoutObj && clearTimeout(this.serverTimeoutObj);
this.timeoutObj = setTimeout(function(){
//这里发送一个心跳,后端收到后,返回一个心跳消息,
//onmessage拿到返回的心跳就说明连接正常
ws.send("123456789"); // 心跳包
_num--;
//计算答复的超时次数
if(_num === 0) {
ws.colse();
}
}, this.timeout)
}
}
我们确认了后端单台服务器的处理能力有限,因此 。我们需要做集群 。其次我们为了不让前端关闭或回收,后端不响应 。我们需要设置心跳,定时清除无关的连接 。最后,我们需要有消息确认机制,做到保证消息的100%接收
推荐阅读
- goroutine的退出与泄露:如何检测和预防
- Python3编写的CMS识别工具 内置安全检测
- 为啥“不合格”却没有处罚 看懂路由器检测
- 淘宝违禁词检测 淘宝禁用词检测查询工具
- 胎心检测多少分正常
- 无人驾驶项目实战:使用OpenCV进行实时车道检测
- OpenSSH用户名枚举及其检测方法
- 红茶茶黄素成分检测?[红茶]
- 附代码 基于NLP的COVID-19虚假新闻检测
- 淘宝怎么排除关键字 淘宝违禁词在线检测