赞
踩
websocket心跳检测的目的用一句话概括就是客户端和服务端保证彼此还活着,避免丢包发生.
websocket断开一般有两种情况
在使用websocket过程中,可能会出现网络断开的情况,比如信号不好,或者网络临时关闭,这时候websocket的连接已经断开,而不同浏览器有不同的机制,触发onclose的时机也不同,并不会理想执行websocket的onclose方法,我们无法知道是否断开连接,也就无法进行重连操作。
如果后端因为一些情况需要断开ws,在可控情况下,会下发一个断连的消息通知,之后才会断开,我们便会重连。
如果因为一些异常断开了连接,我们是不会感应到的,所以如果我们发送了心跳一定时间之后,后端既没有返回心跳响应消息,前端又没有收到任何其他消息的话,我们就能断定后端主动断开了。
因此需要一种机制来检测客户端和服务端是否处于正常连接的状态。通过在指定时间间隔发送心跳包来保证连接正常,如果连接出现问题,就需要手动触发onclose事件,这时候便可进行重连操作。因此websocket心跳重连就应运而生。
2.1 首先通过new WebSocket 实例,来实现WebSocket 连接
//websocket启动 function startWebSocket() { if ('WebSocket' in window) ws = new WebSocket("${ws}/"+employess_number); else if ('MozWebSocket' in window) ws = new WebSocket("${ws}/"+employess_number); //ws = new WebSocket("ws://172.40.1.21:8081/RDWebChat/websocket"); else tishiFunction(1,"浏览器版本不支持!"); //得到消息 ws.onmessage = function(evt){ //心跳检测 // heartCheck.reset().start(); }
2.2 通过WebSocket实例上的一些方法可是实现断开重连
ws.onerror = function(evt){ // console.log(evt,'出错啦'); // wsReconnect(); } ws.onmessage = function(evt){ // console.log(evt,'出错啦'); // wsReconnect(); } ws.onclose = function(evt) { // $('#denglu').html("离线"); heartCheck.reset();//心跳检测 //console.log(evt,'连接关闭了'); // wsReconnect(); }; ws.onopen = function(evt) { //$('#denglu').html("在线"); // $('#userName').html(self); // console.log(evt,'开始连接'); // heartCheck.reset().start(); };
2.3 WebSocket重连
//websocket重连
function wsReconnect(){
if(heartbeat){
return;
}
heartbeat = true;
setTimeout(function(){
console.log('重连中');
heartbeat = false;
startWebSocket();
},2000);
}
2.4 心跳检测
//websocket心跳检测 var heartCheck = { timeout: 30000, timeoutObj: null, serverTimeoutObj: null, reset: function(){ clearTimeout(this.timeoutObj); clearTimeout(this.serverTimeoutObj); return this; }, start: function(){ var self = this; this.timeoutObj = setTimeout(function(){ //这里发送一个心跳,后端收到后,返回一个心跳消息, //onmessage拿到返回的心跳就说明连接正常 ws.send("HeartBeat"); console.log('心跳开始'); self.serverTimeoutObj = setTimeout(function(){//如果超过一定时间还没重置,说明后端主动断开了 console.log('关闭服务'); ws.close();//如果onclose会执行reconnect,我们执行ws.close()就行了.如果直接执行reconnect 会触发onclose导致重连两次 }, self.timeout) }, this.timeout) } }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。