【问题标题】:socket.io bad connection tolerancesocket.io 坏连接容错
【发布时间】:2018-04-11 21:06:14
【问题描述】:

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

我知道 socket.io 实现了一个 HeartBeat 乒乓球的东西,它确保客户端仍然活着,并且在一定时间后超时。

我有两个问题:

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

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

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

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

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

【问题讨论】:

  • 什么是清理?什么时候创建必须清理的对象?
  • 你能描述一下这里真正的问题吗?您在清理过程中实际上想要做什么,然后也许我们可以帮助您更好地了解如何做到这一点。

标签: javascript node.js socket.io disconnect


【解决方案1】:

服务器端的断开事件是不是只有在 心跳超时,比如说 25 秒后或其他什么或它会触发 每次客户失踪一秒钟?

disconnect 事件被触发的原因如下:

  • 客户端断开套接字。
  • 客户端发送 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

如果每次客户失踪时它都会触发 考虑在断开事件处理程序中调用 setTimeout 在确保客户没有清理之后进行清理 重新连接。这是个好方法吗?

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。您可以在文档中找到更多选项。

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

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

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-01-02
    • 2017-01-08
    • 2023-03-18
    • 1970-01-01
    • 2014-02-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多