# 心跳检测
- 服务端:检测客户端的连接 -> 定时器 -> 超过指定时间 -> 主动断开客户端的连接
- 客户端:设置定时器 -> 如果超时或者服务端没有响应 ping/pong -> 断开与服务端的连接
服务端代码:
// 消息处理
ws.on('message', function (msg) {
// ...
var msgObj = JSON.parse(msg)
if (msgObj.event === 'heartbeat' && msgObj.message === 'pong') {
ws.isAlive = true
return
}
// ...
})
// 计时器
const interval = setInterval(function () {
// 遍历所有的客户端,发送一个ping/pong消息
// 检测是否有返回,如果没有返回或者超时之后,主动断开与客户端的连接
wss.clients.forEach(function each(ws) {
if (ws.isAlive === false) {
console.log('client is disconneted!');
group[ws.roomid]--
return ws.terminate()
}
ws.isAlive = false
// 主动发送ping/pong消息
// 客户端返回了之后,主动设置isAlive的状态
ws.send(JSON.stringify({
event: 'heartbeat',
message: 'ping'
}))
})
}, timeInterval)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
客户端的代码:
onOpen: function() {
// 连接创建之时
// 设置定时器 -> 如果超时或者服务端没有响应 ping/pong -> 断开与服务端的连接
console.log("client is connected");
this.checkServer();
},
onMessage: function () {
// 心跳检测
if (msg.event === "heartbeat" && msg.message === "ping") {
this.checkServer();
this.wsHandle.send(
JSON.stringify({
event: "heartbeat",
message: "pong",
})
);
return;
}
//...
}
// 定时器方法
checkServer: function() {
console.log("checkServer in");
// 计时器去定时检测websocket的连接
var _this = this;
clearTimeout(this.handler);
// 超时之后,即会执行
this.handler = setTimeout(function() {
console.log("checkServer fail, close websocket");
// 主动断开服务器端的连接
_this.onClose();
}, 5000 + 1000);
},
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35