# 心跳检测

  • 服务端:检测客户端的连接 -> 定时器 -> 超过指定时间 -> 主动断开客户端的连接
  • 客户端:设置定时器 -> 如果超时或者服务端没有响应 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

客户端的代码:

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
上次更新: 2020/10/28 下午11:02:30