我使用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的客户端连接很多流量。我无法想象,同时运行的10k计时器可由NodeJS处理。 更糟糕:我读到如果没有时间,NodeJS将不会触发该事件。
如何实现一个良好的工作和高效的数据包确认系统?
答案 0 :(得分:2)
如果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);
实际上没有超时的开销;它基本上只是被放入队列,直到执行它为止。
答案 1 :(得分:1)
我读到如果没有时间,NodeJS将不会触发该事件。
这有点夸张,node.js计时器是可靠的。由setTimeout 设置的计时器将在某个时刻触发。如果进程在确切的预定时间忙,则可能会延迟,但最终将调用回调。
引自Node.js docs for setTimeout:
可能不会在精确延迟的毫秒内调用回调。 Node.js不保证回调何时触发的确切时间,也不保证它们的排序。回调将尽可能接近指定的时间调用。