一、何为心跳?
心跳就是客户端定时的给服务端发送消息,证明客户端是在线的, 如果超过一定的时间没有发送则就是离线了。
二、如何判断在线离线?
当客户端第一次发送请求至服务端时会携带唯一标识、以及时间戳,服务端到db或者缓存去查询改请求的唯一标识,如果不存在就存入db或者缓存中,
第二次客户端定时再次发送请求依旧携带唯一标识、以及时间戳,服务端到db或者缓存去查询改请求的唯一标识,如果存在就把上次的时间戳拿取出来,使用当前时间戳减去上次的时间,
得出的毫秒秒数判断是否大于指定的时间,若小于的话就是在线,否则就是离线;
三、若服务端宕机了,客户端怎么做、服务端再次上线时怎么做?
客户端则需要断开连接,通过onclose 关闭连接,服务端再次上线时则需要清除之间存的数据,若不清除 则会造成只要请求到服务端的都会被视为离线。
具体代码如下:
var socket; //websocket的实例
var lockReconnect = false; //避免重复连接
function getwebsocket() { //新建websocket的函数 页面初始化 断开连接时重新调用
var wsUrl = 'ws://10.200.101.121:9001/websocket?wsToken=' + window.token + '&djxh=' + window.djxh;
socket = new WebSocket(wsUrl);
socket.onerror = function(event) {
//console.log('websocket服务出错了');
reconnect(wsUrl);
};
socket.onclose = function(event) {
//console.log('websocket服务关闭了');
reconnect(wsUrl);
};
socket.onopen = function(event) {
heartCheck.reset().start(); //传递信息
};
socket.onmessage = function(event) {
//如果获取到消息,心跳检测重置
//拿到任何消息都说明当前连接是正常的
//console.log('websocket服务获得数据了');
//接受消息后的UI变化
doWithMsg(event.data);
heartCheck.reset().start();
};
//收到消息推送
function doWithMsg(msg) {
getdjxh() //这个函数是业务上面申请列表的函数 可以忽略
window.external.CallFun('receiveMsg'); //这个也是
}
}
// 重新链接
function reconnect(url) {
if (lockReconnect) return;
lockReconnect = true;
//没连接上会一直重连,设置延迟避免请求过多
setTimeout(function() {
getwebsocket();
lockReconnect = false;
}, 2000);
}
//心跳检测
var heartCheck = {
timeout: 60000, //60秒
timeoutObj: null,
serverTimeoutObj: null,
reset: function() {
clearTimeout(this.timeoutObj);
clearTimeout(this.serverTimeoutObj);
return this;
},
start: function() {
var self = this;
this.timeoutObj = setTimeout(function() {
//这里发送一个心跳,后端收到后,返回一个心跳消息,
//onmessage拿到返回的心跳就说明连接正常
socket.send("心跳测试");
//如果超过一定时间还没重置,说明后端主动断开了
self.serverTimeoutObj = setTimeout(function() {
//如果onclose会执行reconnect,我们执行ws.close()就行了.
//如果直接执行reconnect 会触发onclose导致重连两次
socket.close();
}, self.timeout)
}, this.timeout)
}
}