NodeJS,Socket.io
想象有两个用户 U1 和 U2 通过Socket.io连接到应用程序。该算法如下:
我想我明白为什么会这样:
如何防止这种数据丢失?我必须使用心跳,因为我不会有人永远挂在应用程序中。另外,我仍然必须提供重新连接的可能性,因为当我部署新版本的应用程序时,我希望停机时间为零。
PS我称之为“消息”的东西不仅是我可以存储在数据库中的文本消息,而且是有价值的系统消息,必须保证其传递或UI搞砸。
谢谢!
我已经有一个用户帐户系统。而且,我的应用程序已经很复杂。添加离线/在线状态将无济于事,因为我已经有了这种东西。问题不同。
签出第2步。从技术上讲,在这一步上我们 不能说U1是否脱机
,他只是失去了连接状态,说了2秒钟,这可能是因为互联网状况不佳。因此,U2向他发送了一条消息,但是U1没有收到该消息,因为互联网对他来说仍然不可用(步骤3)。需要步骤4来检测脱机用户,可以说超时是60秒。最终在另外10秒内,U1的互联网连接建立,他重新连接到socket.io。但是来自U2的消息在空间中丢失了,因为服务器U1上的超时已断开连接。
那就是问题,我不会100%交货。
断开连接或/和/或连接时,如有必要,请向用户冲洗{}
// Server
const pendingEmits = {};
socket.on(‘reconnection’, () => resendAllPendingLimits);
socket.on(‘confirm’, (emitID) => { delete(pendingEmits[emitID]); });
// Client
socket.on(‘something’, () => {
socket.emit(‘confirm’, emitID);
});
添加2020年2月1日。
尽管这并不是Websockets的真正解决方案,但仍然有人可以使用。我们从Websockets迁移到SSE +
Ajax。SSE允许您从客户端进行连接,以保持持久的TCP连接并实时接收来自服务器的消息。要将消息从客户端发送到服务器-
只需使用Ajax。存在诸如延迟和开销之类的缺点,但是SSE保证了可靠性,因为它是TCP连接。
由于我们使用Express,因此我们将此库用于SSE https://github.com/dpskvn/express-
sse,但是您可以选择适合您的库。
其他人已经在其他答案和评论中暗示了这一点,但是根本问题是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
});
这与上一个建议非常相似,只是没有持久性数据存储。
您可能还对事件源的概念感兴趣。
NodeJS,socket.io null null 附言。我称之为“消息”的东西不仅仅是可以存储在数据库中的文本消息,而是有价值的系统消息,必须保证交付,否则UI就会出错。 谢了! 我已经有了一个用户帐户系统。而且,我的应用程序已经很复杂了。添加脱机/联机状态没有帮助,因为我已经有了这类东西。问题不一样。 查看步骤2。在这一步上,我们技术上不能说如果U1离线,他只是失去连接,比如说2秒钟,可能是
问题内容: 在生产中,我有一个使用连接局部变量保存游戏状态的游戏。但是,我注意到,如果我在连接上闲置了一段时间,它将断开连接并重新连接,这将丢失当前状态。在本地主机上进行测试时,我从未注意到此行为。这是套接字连接的规范行为,还是导致连接断开的其他原因。 如果是正常行为,通常如何处理?是否应该将连接值全局存储,以便用户断开/重新连接时可以恢复连接值? 问题答案: 您的问题与套接字超时有关。如果某个套
问题内容: 更新: 我在驱动程序上使用2.1版本,而不是3.2 我有一个使用MongoDB的节点应用程序。我的问题是,如果MongoDB服务器由于任何原因而关闭,则应用程序不会重新连接。为了实现这一点,我基于此官方教程中的代码进行了测试。 想法是运行此脚本,然后停止mongod,然后重新启动它。所以,我们开始: 将MongoDb停止10秒钟可以达到预期效果:它将停止运行查询10秒钟,然后在服务器返
我编写了一些逻辑,同时表示与exchange的近200个websocet连接。我使用第三方api,它基于org.eclipse.jetty.webSocket.api。我有一个我必须重写的方法。 我在stackoverflow上找到了这个问题,但我看不到清晰的答案。请帮忙,提前谢谢。
问题内容: 我尝试使用nginx设置nodejs。但是当客户端尝试连接时,它将失败并显示… 那么如何启用websocket通信呢? 我目前的Nginx配置 问题答案: 首先,将您的nginx服务器升级到1.3或更高版本。 其次,我的nginx conf有效。您可以关注我的conf。
我正在使用套接字。io,应用程序由AWS提供。我收到一个浏览器控制台错误: websocket.js:54 WebSocket 连接到 'wss://www.tidee.com/socket.io/?EIO=4 客户代码: 服务器代码: 在 AWS 中,安全组接受端口 443,负载均衡器侦听端口 443。 应用程序在本地运行时工作(状态 101),并使用 协议。