套接字在断开连接后无法清理

时间:2019-01-13 21:33:54

标签: javascript node.js sockets socket.io

我要解决一个特殊的问题。在服务器上,我有以下代码...

// Establish a connection with a WebSocket.
io.on("connection", socket => {

  setTimeout(sendHeartbeat, 25000);

  function sendHeartbeat(){
    setTimeout(sendHeartbeat, 25000);
    io.sockets.emit("ping", socket.id);
    console.log(io.sockets.adapter.rooms);
  }

});

正在发生的事情是,我每25秒对所有现有的套接字ping一次客户端,然后发送连接的客户端的套接字ID。

在客户端,我只是在监听结果并将其打印到控制台...

socket.on('ping',function(data) {
  console.log(data);
});

我启动服务器并建立连接,在服务器上,我有以下信息...

{ QofufgzXeTqGJcLOAAAA: Room { sockets: { QofufgzXeTqGJcLOAAAA: true }, length: 1 } }

这是正确的,因为只有1个连接,但是在客户端,每隔25秒,控制台将显示如下...

undefined
QofufgzXeTqGJcLOAAAA

不确定undefined的来源。

我继续让服务器运行,最终套接字断开然后再重新连接(这种情况时不时发生),在这种情况下,应删除旧的套接字并用新的套接字替换,这恰好发生在服务器...

{ o2UFD7iHNxc94bPHAAAB: Room { sockets: { o2UFD7iHNxc94bPHAAAB: true }, length: 1 } }

但是在客户端,每25秒打印以下内容...

undefined
QofufgzXeTqGJcLOAAAA
o2UFD7iHNxc94bPHAAAB

我试图了解为什么旧的插槽没有被移除。每次断开连接时,似乎都添加了一个额外的套接字。我怎样才能解决这个问题?在上面的示例中,应该仅将一个套接字ID打印到控制台。

2 个答案:

答案 0 :(得分:0)

您可以将其更改为io.once("connection"),这意味着每次连接时,它不会添加其他绑定,或者您可以订阅断开连接事件,并在连接中断时取消绑定此事件。我倾向于第二种方法,因为它可以使代码更简洁,以后的wtf时间更少

答案 1 :(得分:0)

对我有用的解决方案是将c("AAA", "BBB", "CCC")setInterval一起使用。之所以要在控制台上打印多个套接字,是因为递归函数从未清除,因此所有实例都异步运行。

我的新解决方案如下...

clearInterval

...然后断开连接,我就会...

// Ping the client to prevent disconnect.
let keepAlive = setInterval(sendHeartbeat, 25000);
function sendHeartbeat(){
    io.sockets.emit("ping", socket.id);
    console.log(io.sockets.adapter.rooms);
}

这解决了我的问题,现在我只能按预期将1个套接字打印到控制台上。我仍然也可以使用socket.on("disconnect", async () => { clearInterval(keepAlive); }); ,但是要解决此问题answer可以解决此问题。

基本上, socket.io 需要一段时间才能建立连接,因此undefined可用于检查是否建立了连接。这将从控制台中删除socket.on('connection', ...)