为了证实客户端和服务器还活着。websocket 在应用过程中,如果遭逢网络问题等,这个时候服务端没有触发onclose事件,这样会产生多余的连贯,并且服务端会持续发送音讯给客户端,造成数据失落。因而须要一种机制来检测客户端和服务端是否处于失常连贯的状态,心跳检测和重连机制就产生了。
如何进行心跳检测和游戏重连
思路是:
每隔一段指定的工夫(计时器),向服务器发送一个数据,服务器收到数据后再发送给客户端,失常状况下客户端通过onmessage事件是能监听到服务器返回的数据的,阐明申请失常。
如果再这个指定工夫内,客户端没有收到服务器端返回的响应音讯,就断定连贯断开了,应用websocket.close敞开连贯。
这个敞开连贯的动作能够通过onclose事件监听到,因而在 onclose 事件内,咱们能够调用reconnect事件进行重连操作http://www.lyouxi.com。
具体代码实现
$(function () {
var path = basePath;
var jspCode = $("#userId").val();
var websocket;
createWebSocket();
/**
- websocket启动
*/
function createWebSocket() {
try {
if ('WebSocket' in window) {
websocket = new WebSocket((path + "/wsCrm?jspCode=" + jspCode).replace("http", "ws").replace("https", "ws"));
} else if ('MozWebSocket' in window) {
websocket = new MozWebSocket(("ws://" + path + "/wsCrm?jspCode=" + jspCode).replace("http", "ws").replace("https", "ws"));
} else {
websocket = new SockJS(path + "/wsCrm/sockJs?jspCode=" + jspCode.replace("http", "ws"));
}
init();
} catch (e) {
console.log('catch' + e);
reconnect();
}
}
function init() {
//连贯胜利建设的回调办法
websocket.onopen = function (event) {
console.log("WebSocket:已连贯");
//心跳检测重置
heartCheck.reset().start();
};
//接管到音讯的回调办法
websocket.onmessage = function (event) {
showNotify(event.data);
console.log("WebSocket:收到一条音讯", event.data);
heartCheck.reset().start();
};
//连贯产生谬误的回调办法
websocket.onerror = function (event) {
console.log("WebSocket:产生谬误");
reconnect();
};
//连贯敞开的回调办法
websocket.onclose = function (event) {
console.log("WebSocket:已敞开");
heartCheck.reset();//心跳检测
reconnect();
};
//监听窗口敞开事件,当窗口敞开时,被动去敞开websocket连贯,避免连贯还没断开就敞开窗口,server端会抛异样。
window.onbeforeunload = function () {
websocket.close();
};
//敞开连贯
function closeWebSocket() {
websocket.close();
}
//发送音讯
function send(message) {
websocket.send(message);
}
}
//防止反复连贯
var lockReconnect = false, tt;
/**
- websocket重连
*/
function reconnect() {
if (lockReconnect) {
return;
}
lockReconnect = true;
tt && clearTimeout(tt);
tt = setTimeout(function () {
console.log('重连中...');
lockReconnect = false;
createWebSocket();
}, 4000);
}
/**
- websocket心跳检测
*/
var heartCheck = {
timeout: 5000,
timeoutObj: null,
serverTimeoutObj: null,
reset: function () {
clearTimeout(this.timeoutObj);
clearTimeout(this.serverTimeoutObj);
return this;
},
start: function () {
var self = this;
this.timeoutObj && clearTimeout(this.timeoutObj);
this.serverTimeoutObj && clearTimeout(this.serverTimeoutObj);
this.timeoutObj = setTimeout(function () {
//这里发送一个心跳,后端收到后,返回一个心跳音讯,
//onmessage拿到返回的心跳就阐明连贯失常
websocket.send("HeartBeat");
console.log('ping');
self.serverTimeoutObj = setTimeout(function () { // 如果超过肯定工夫还没重置,阐明后端被动断开了
console.log('敞开服务');
websocket.close();//如果onclose会执行reconnect,咱们执行 websocket.close()就行了.如果间接执行 reconnect 会触发onclose导致重连两次
}, self.timeout)
}, this.timeout)
}
};
});