概述
websocket心跳和重连
在web应用场景中,经常有服务器向客户端推送消息的场景需求,比如实时更新日志、客服聊天、联网的游戏、直播互动等等,有时需要浏览器端的用户一直保持点对点通讯,此情此景,最好的选择是websocket,因为从稳定性、服务器资源开销都是最优的。
但是,即使最优选择也不能保证一直通讯正常,因为网络中断的情况,谁也无法保证不发生,也无从预料。这种情形下,websocket心跳和重连就有了用武之地。
永前科技有必要提醒一下,请有前端外包需求的朋友,一定要关注这一点,这是关乎web应用产品的重要质量指标。
1. 心跳重连原由
websocket心跳和重连的目的用一句话概括就是客户端和服务端保证彼此还活着,避免丢包发生。
websocket连接断开有以下两证情况:
前端断开
在使用websocket过程中,可能会出现网络断开的情况,比如信号不好,或者网络临时关闭,这时候websocket的连接已经断开,而不同浏览器有不同的机制,触发onclose的时机也不同,并不会理想执行websocket的onclose方法,我们无法知道是否断开连接,也就无法进行重连操作。
后端断开
如果后端因为一些情况需要断开ws,在可控情况下,会下发一个断连的消息通知,之后才会断开,我们便会重连。
如果因为一些异常断开了连接,我们是不会感应到的,所以如果我们发送了心跳一定时间之后,后端既没有返回心跳响应消息,前端又没有收到任何其他消息的话,我们就能断定后端主动断开了。
因此需要一种机制来检测客户端和服务端是否处于正常连接的状态。通过在指定时间间隔发送心跳包来保证连接正常,如果连接出现问题,就需要手动触发onclose事件,这时候便可进行重连操作。因此websocket心跳重连就应运而生。
2. 心跳重连的简单实现
2.1 通过createWebSocket创建连接
function createWebSocket() {
try {
ws = new WebSocket(wsUrl);
init();
} catch(e) {
console.log('catch');
reconnect(wsUrl);
}
}
2.2 创建init方法,初始化一些监听事件,如果希望websocket连接一直保持, 我们会在close或者error上绑定重新连接方法。
function init() {
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();
}
}
2.3 重连操作,通过设置lockReconnect变量避免重复连接
var lockReconnect = false;//避免重复连接
function reconnect(url) {
if(lockReconnect) {
return;
};
lockReconnect = true;
//没连接上会一直重连,设置延迟避免请求过多
tt && clearTimeout(tt);
tt = setTimeout(function () {
createWebSocket(url);
lockReconnect = false;
}, 4000);
}
2.4 心跳检测
//心跳检测
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)
}
}
有的时候,客户端发送3次心跳包服务端均未回复才判定为失去连接,所以这时需要加上计数来判断。
//心跳检测
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)
}
}
总结
虽然websocket已经非常高效,也足够优化,但是在业务需求压力很大情况,可以使用集群服务,然后配合使用消息确认机制,可以确保推送的消息能100%接收,做到万无一失,做高品质互联网产品。
最后
以上就是风趣秀发为你收集整理的websocket心跳和重连websocket心跳和重连的全部内容,希望文章能够帮你解决websocket心跳和重连websocket心跳和重连所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复