socket.io 错误的连接容差

socket.io bad connection tolerance

我需要实现一个能够容忍客户端和服务器之间偶尔断开连接的系统。

我知道 socket.io 实现了 HeartBeat ping pong 功能,确保客户端仍然存在并且在一定时间后超时。

我有两个问题:

所以在代码中应该是这样的:

socket.on('disconnect', function(){
   setTimeout(cleanup, 8000);
});

function cleanup(){
    if(socket.connected) return;
    // clean up
}

Is the disconnect event on the server side only called when the Heartbeat times out, say after 25 seconds or whatever or does it fire every time a client goes missing for a second?

由于以下原因触发断开连接事件:

  • 客户端断开套接字。
  • 客户端发送DISCONNECT命令。
  • 客户端在 X 毫秒内未发送 'ping'。

服务器必须每 X 毫秒接收一次来自客户端的 ping,否则它会断开套接字。

默认 X = 5000 毫秒(5 秒)

因此服务器希望客户端每 5 秒发送一个 'ping'。默认情况下,客户端将每 2000 毫秒(每 2 秒)发送一个 'ping'。

您可以按如下方式配置这些值:

var app = require('express')();
var http = require('http').Server(app);

var io = require('socket.io')(http, {
    pingInterval: 2000, // How many ms before the client sends a new ping packet
    pingTimeout': 5000, // How many ms without a pong packet to consider the connection closed.
});

评论来自docs

In the case it fires every single time a client goes missing I was thinking of calling a setTimeout in the disconnect event handler that does the clean up after it had made sure that the client has not reconnected. Is that a good approach?

socket.io 客户端支持重新连接,因此您应该尝试一下,看看是否按您想要的方式工作。否则您可以手动实现重连。

以下是如何在 client-side

上配置重新连接
io.connect('http://localhost', {
  reconnection: true, // Whether to reconnect automatically (default: true)
  reconnectionDelay: 500, // Number of reconnection attempts before giving (default: Infinity)
  reconnectionAttempts: 10, // How long to initially wait before attempting a new reconnection (default: 1000)

});

评论再次取自 docs。您会发现文档中列出了更多选项。

请注意,从服务器的角度来看,重新连接的客户端是 客户端。我不认为它有任何理解它是一个断开连接的客户端回来。

所以我想说简单的解决方案是立即清理(没有 setTimeout)并让系统处理任何重新连接,就好像它是一个新套接字一样。

如果清理是某种缓存,并且重新生成缓存的成本非常高,那么也许您确实想尝试为重新连接的客户端重用缓存。在这种情况下,您可能希望在客户端中生成一个 GUID,当客户端连接或重新连接时传递给服务器,以便您的服务器可以 re-identify 重新连接的套接字并将其重新附加到它的缓存数据记录。这会变得混乱,如果可以的话,最好坚持使用简单的解决方案。

另一种方法可能是经常对缓存进行垃圾回收,而不是执行 setTimeout。保留客户端最后一次使用它的记录(在缓存中)。每 30 分钟(或您选择的任何时间间隔)检查缓存并删除一段时间未见的客户端的记录。在这种情况下,您还需要使用 GUID 方法,以便重新连接的客户端可以重新附加到它们的缓存记录。