igo*_*lov 72 node.js socket.io
NodeJS,Socket.io
想象一下,有2个用户U1和U2,通过Socket.io连接到应用程序.算法如下:
我想我明白为什么会这样:
如何防止这种数据丢失?我必须使用hearbeats,因为我没有人永远挂在应用程序中.此外,我仍然必须重新连接,因为当我部署新版本的应用程序时,我希望零停机时间.
PS我称之为"消息"的东西不仅仅是我可以存储在数据库中的文本消息,而是有价值的系统消息,必须保证交付,或UI搞砸了.
谢谢!
我已经有了一个用户帐户系统.而且,我的申请已经很复杂了.添加离线/在线状态无济于事,因为我已经有了这种东西.问题不同了.
检查第2步.在这一步我们技术上不能说U1是否脱机,他只是失去连接让我说2秒,可能是因为互联网不好.所以U2给他发了一条消息,但U1没有收到它,因为互联网仍在为他服务(步骤3).需要步骤4来检测离线用户,假设超时为60秒.最后,在另一个10秒内,U1的互联网连接正常,他重新连接到socket.io.但来自U2的消息在空间中丢失,因为服务器U1在超时时断开连接.
这是问题,我不是100%交付.
在必要时断开连接或/和连接flush {}
//服务器const pendingEmits = {};
socket.on('reconnection',()=> resendAllPendingLimits); socket.on('confirm',(emitID)=> {delete(pendingEmits [emitID]);});
// Client socket.on('something',()=> {socket.emit('confirm',emitID);});
Mic*_*ley 85
其他人在其他答案和评论中暗示了这一点,但根本问题是Socket.IO只是一种交付机制,你无法单独依靠它来实现可靠的交付.唯一确定消息已成功传递给客户端的人是客户端本身.对于这种系统,我建议做出以下断言:
当然,根据您的应用程序的需要,您可以调整其中的一部分 - 例如,您可以使用Redis列表或消息的排序集,如果您知道客户端已启动,请将其清除至今.
以下是几个例子:
快乐的道路:
离线路径:
如果您绝对需要保证交付,那么设计您的系统非常重要,因为连接实际上并不重要,而实时交付只是一个奖励 ; 这几乎总是涉及某种数据存储.正如评论中提到的user568109,有消息传递系统抽象出所述消息的存储和传递,并且可能值得研究这样的预构建解决方案.(您可能仍需要自己编写Socket.IO集成.)
如果您对将消息存储在数据库中不感兴趣,则可以将它们存储在本地阵列中; 服务器尝试向U1发送消息,并将其存储在"待处理消息"列表中,直到U1的客户端确认它已收到消息.如果客户端处于脱机状态,那么当它返回时,它可以告诉服务器"嘿,我已经断开连接,请将我错过的任何内容发送给我",服务器可以迭代这些消息.
幸运的是,Socket.IO提供了一种机制,允许客户端"响应"看起来像本机JS回调的消息.这是一些伪代码:
// server
pendingMessagesForSocket = [];
function sendMessage(message) {
pendingMessagesForSocket.push(message);
socket.emit('message', message, function() {
pendingMessagesForSocket.remove(message);
}
};
socket.on('reconnection', function(lastKnownMessage) {
// you may want to make sure you resend them in order, or one at a time, etc.
for (message in pendingMessagesForSocket since lastKnownMessage) {
socket.emit('message', message, function() {
pendingMessagesForSocket.remove(message);
}
}
});
// client
socket.on('connection', function() {
if (previouslyConnected) {
socket.emit('reconnection', lastKnownMessage);
} else {
// first connection; any further connections means we disconnected
previouslyConnected = true;
}
});
socket.on('message', function(data, callback) {
// Do something with `data`
lastKnownMessage = data;
callback(); // confirm we received the message
});
Run Code Online (Sandbox Code Playgroud)
这与上一个建议完全相似,只是没有持久数据存储.
您可能也对事件采购的概念感兴趣.