Websocket传输可靠性(重新连接期间Socket.io数据丢失)
用过的 NodeJS,Socket.io 问题 假设有两个用户U1和U2通过Socket.io连接到应用程序。该算法如下: U1完全失去Internet连接(例如,关闭Internet) U2向U1发送消息。 U1尚未收到消息,因为Internet断开 服务器通过心跳超时检测到U1断开连接 U1重新连接到socket.io U1从不接收来自U2的消息-我猜它在步骤4中丢失了。 可能的解释 我想我明白为什么会这样: 第4步服务器杀死Socket实例和消息队列U1以及 此外,在步骤5 U1和服务器上创建新连接(不重用),因此,即使消息仍在排队中,仍然会丢失先前的连接。 需要帮忙 如何防止这种数据丢失?我必须使用心跳,因为我没有人永远挂在应用程序上。另外,我仍然必须提供重新连接的可能性,因为当我部署新版本的应用程序时,我希望停机时间为零。 PS我称之为“消息”的东西不仅是我可以存储在数据库中的文本消息,而且是有价值的系统消息,必须保证其传递或UI搞砸。 谢谢! 加法1 我已经有一个用户帐户系统。而且,我的应用程序已经很复杂。添加离线/在线状态将无济于事,因为我已经有了这种东西。问题不同。 签出第2步。从技术上讲,我们无法说出U1是否脱机,他只是失去了连接状态,说了2秒钟,这可能是因为互联网状况不佳。因此,U2向他发送了一条消息,但是U1没有收到该消息,因为互联网对他来说仍然不可用(步骤3)。需要步骤4来检测脱机用户,可以说超时为60秒。最终在另外10秒钟内,U1的互联网连接建立,他重新连接到socket.io。但是来自U2的消息在空间中丢失,因为服务器U1上的超时已将其断开连接。 那就是问题,我不会100%交货。 解 收集{}用户中的发射(发射名称和数据),由随机的emitID标识。发送发射 在客户端确认发射(将发射发送回带有emitID的服务器) 如果已确认-从{}中删除由emitID标识的对象 如果用户重新连接-为该用户检查{}并遍历该用户,则对{}中的每个对象执行步骤1 断开连接或/和/或连接时,如有必要,请向用户冲洗{} // Server const pendingEmits = {}; socket.on('reconnection', () => resendAllPendingLimits); socket.on('confirm', (emitID) => { delete(pendingEmits[emitID]); }); // Client socket.on('something', () => …