javascript - socket.io 不良连接容忍度

标签 javascript node.js socket.io disconnect

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

据我了解,socket.io 实现了 HeartBeat ping pong 功能,可确保客户端仍然处于事件状态,并在一定时间后超时。

我有两个问题:

  • 服务器端的断开连接事件是否仅在心跳超时(例如 25 秒或其他时间后)时调用,或者每次客户端丢失一秒钟时都会触发?

  • 如果每次客户端丢失时都会触发,我正在考虑在 disconnect 事件处理程序中调用 setTimeout ,该处理程序会在之后进行清理它已确保客户端尚未重新连接。这是一个好方法吗?

所以在代码中它会是这样的:

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 客户端支持重新连接,因此您应该尝试一下,看看是否按您想要的方式工作。否则您可以手动实现重新连接。

以下是在客户端配置重新连接的方法

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 。您会发现文档中列出了更多选项。

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

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

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

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

关于javascript - socket.io 不良连接容忍度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49784464/

相关文章:

javascript - 使用 CSS 列在 epub 上工作,关于分页

javascript - Kurento webRTC 流媒体服务器 - Chrome 问题

javascript - 如何在 Redux 中更新状态后触发关闭回调?

javascript - Svelte - 监视组件外部组件属性的更改(访问器)

node.js - 如何从express-stormpath库中自定义注销的redirectURL?

node.js - expressjs 和 socket.io - 客户端上的重复消息

javascript - 我需要担心 Node.js 中的并发修改吗?

node.js - backbone.js + node.js - express.js

javascript - JSLint错误: "Expected a newline at EOF",与Beautify插件冲突

node.js - 如何从 express-session 获取当前 session 信息?