代码之家  ›  专栏  ›  技术社区  ›  buydadip

断开后插座不清理

  •  1
  • buydadip  · 技术社区  · 7 年前

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

    // 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 } }
    

    这是正确的,因为只有一个连接,但是在客户端,每25秒,控制台看起来如下…

    undefined
    QofufgzXeTqGJcLOAAAA
    

    不确定在哪里 undefined 来自于。

    我继续让服务器运行,最终套接字断开连接,然后重新连接(这种情况不时发生),在这种情况下,旧的套接字应该被删除并替换为新的套接字,这正是服务器上发生的事情……

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

    但在客户端,以下内容每25秒打印一次…

    undefined
    QofufgzXeTqGJcLOAAAA
    o2UFD7iHNxc94bPHAAAB
    

    我在试着理解为什么旧的插座不能被拔掉。在每次断开时,似乎都会添加一个额外的套接字。我怎么修这个?在上面的示例中,只有一个套接字ID应该打印到控制台。

    2 回复  |  直到 7 年前
        1
  •  0
  •   buydadip    7 年前

    你可以把这个改成 io.once("connection") 这意味着每次连接时,它不会添加额外的绑定,或者您可以订阅断开连接事件,并在连接中断时从该事件解除绑定。我倾向于采用第二种方法,因为它会导致代码更干净,稍后会减少wtf。

        2
  •  0
  •   buydadip    7 年前

    对我有效的解决方案是 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);
    }
    

    …断开连接后我会…

    socket.on("disconnect", async () => {
      clearInterval(keepAlive);
    });
    

    这解决了我的问题,现在我只得到1个插座打印到控制台,如预期的那样。我仍然得到 undefined 还有一个,但为了解决这个问题 answer 解释如何解决问题。

    基本上,这需要一段时间 插座 建立联系,这样 socket.on('connection', ...) 可用于检查是否建立了连接。这将删除 未定义 从控制台。