今天有个需求就是监听app时时在线人数,本来打算用Session来实现监听的,利用监听器,可是后来发现用sessionnd的话 耗服务器资源,还需要注意关闭浏览器不能及时删除session, 不同浏览器打开网页后会多余统计的情况,同时http是无序的, 服务器必须使用建立TCP会话来确认, 并且不准确,所以在师傅是指导下用Webscoket来监听心跳来实现这个功能。
实现心跳检测的思路是:每隔一段固定的时间,向服务器端发送一个ping数据,如果在正常的情况下,服务器会返回一个pong给客户端,如果客户端通过onmessage事件能监听到的话,说明请求正常,这里我们使用了一个定时器,每隔3秒的情况下,如果是网络断开的情况下,在指定的时间内服务器端并没有返回心跳响应消息,因此服务器端断开了,因此这个时候我们使用ws.close关闭连接,在一段时间后(在不同的浏览器下,时间是不一样的,firefox响应更快),可以通过 onclose事件监听到。因此在onclose事件内,我们可以调用 reconnect事件进行重连操作。客户端代码如下,如有不对请各路大神指导:
<html>
<head>
<meta charset="utf-8">
<title>WebSocket Demo</title>
</head>
<body>
<script type="text/javascript">
// var ws = new WebSocket("wss://echo.websocket.org");
/*
ws.onerror = function(e) {
console.log('已关闭');
};
ws.onopen = function(e) {
console.log('握手成功');
ws.send('123456789');
}
ws.onclose = function() {
console.log('已关闭');
}
ws.onmessage = function(e) {
console.log('收到消息');
console.log(e);
}
*/
var lockReconnect = false;//避免重复连接
var wsUrl = "wss://echo.websocket.org";
var ws;
var tt;
function createWebSocket() {
try {
ws = new WebSocket(wsUrl);
init();
} catch(e) {
console.log('catch');
reconnect(wsUrl);
}
}
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();
}
}
function reconnect(url) {
if(lockReconnect) {
return;
};
lockReconnect = true;
//没连接上会一直重连,设置延迟避免请求过多
tt && clearTimeout(tt);
tt = setTimeout(function () {
createWebSocket(url);
lockReconnect = false;
}, 4000);
}
//心跳检测
var heartCheck = {
timeout: 3000,
timeoutObj: null,
serverTimeoutObj: null,
start: function(){
console.log('start');
var self = this;
this.timeoutObj && clearTimeout(this.timeoutObj);
this.serverTimeoutObj && clearTimeout(this.serverTimeoutObj);
this.timeoutObj = setTimeout(function(){
//这里发送一个心跳,后端收到后,返回一个心跳消息,
console.log('55555');
ws.send("123456789");
self.serverTimeoutObj = setTimeout(function() {
console.log(111);
console.log(ws);
ws.close();
// createWebSocket();
}, self.timeout);
}, this.timeout)
}
}
createWebSocket(wsUrl);
</script>
</body>
</html>