2

我正在使用 socket.io 通过 websockets 发送数据包。它们似乎不时消失。所以我必须实施某种确认系统。我的想法是立即使用 ACK 数据包响应数据包。如果服务器在给定时间内没有收到这个 ACK​​ 包,他将重新发送它(最多 3 次,然后断开套接字)。

我的第一个想法是在发送数据包后启动一个计时器(setTimeout)。如果发生超时事件,则必须再次发送数据包。如果 ACK 将到达,超时将被删除。很简单也很简短。

var io = require('socket.io').listen(80);

// ... connection handling ...

function sendData(someData, socket) {
  // TODO: Some kind of counter to stop after 3 tries.
  socket.emit("someEvent", someData);
  var timeout = setTimeout(function(){ sendData(someData, socket); }, 2000);
  socket.on("ack", function(){
    // Everything went ok.
    clearTimeout(timeout);
  });
}

但是我将有 1k-3k 客户端连接到大量流量。我无法想象,NodeJS 可以处理同时运行的 10k 个计时器。更糟糕的是:我读到如果没有时间,NodeJS 不会触发该事件。

如何实现一个工作良好且高效的数据包确认系统?

4

2 回答 2

3

如果 socket.io 对您来说不够可靠,您可能需要考虑实现自己的 websocket 接口,而不是在 socket.io 之上添加一个层。但是要回答您的问题,我认为运行 10k 计时器没什么大不了的。例如,以下代码对我来说在 3 秒内运行并打印出预期的结果100000

var x = 0;
for (var i = 0; i < 100000; i++) {
    setTimeout(function() { x++; }, 1000);
}

setTimeout(function() { console.log(x); }, 2000);

超时实际上并没有那么多开销。它基本上只是被放入队列中,直到执行它。

于 2013-08-14T08:55:10.617 回答
1

我读到如果没有时间,NodeJS 不会触发该事件。

这有点夸张,node.js 的定时器是可靠的。由 setTimeout 设置的计时器在某个时候触发。如果进程在确切的预定时间忙,它可能会延迟,但最终会调用回调。

引用自Node.js 文档的 setTimeout

回调可能不会在精确的延迟毫秒内被调用。Node.js 不保证回调何时触发的确切时间,也不保证它们的顺序。回调将在尽可能接近指定时间时被调用。

于 2018-03-07T09:26:34.383 回答