我遇到Socket.io在页面导航发生之前接收消息的问题 - 通常是当消息是导航触发的某些服务器端操作的直接结果时。
我现在看到的是这样的:
这本身并不是一个错误,因为我不认为期望Socket.io在导航发生之前关闭连接是合理的。但是,我不确定最好的办法是什么。目前,我每个客户端一次打开一个连接,并在新连接时关闭另一个连接。但是,在这种情况下不会发生这种情况,因为第一个在第二个连接之前已经关闭。我也可以保留所有客户端的列表,但这也不能解决这个问题,因为第一次连接仍然会收到该消息。
有人可以建议解决此问题,以确保用户始终看到该消息的通知吗?
答案 0 :(得分:4)
Socket.io使用自己的会话ID跟踪逻辑连接。如果您在客户端连接时观察控制台,您将看到ID:
info - handshake authorized Q9syoIK47JI7dACYpxiA
重要的是要了解这些ID 每页,与HTTP会话完全分开。 Socket.io客户端库只是将其会话ID保存在JavaScript变量中。因此,在导航时,ID显然会丢失。
因此,在导航时,会发生这种情况:
1
的页面上。window.onbeforeunload
上,Socket.io initiates a synchronous XHR request告诉服务器它正在断开连接。如果成功,会话(1
)立即终止;否则,会议最终会超时。2
。1
的任何内容显然都不会发送,因为我们的客户现已连接到会话2
。使用基本的Socket.io功能,无法区分在页面之间导航的用户和新用户。在任何一种情况下,用户都将连接到新的Socket.io会话。
如果不确切知道您的应用是如何运作的,或者您想要完成的是什么,很难给出解决问题的明确建议。
最有可能的是,您需要做的是associate a Socket.io session with the user's HTTP session。您可以将通知存储在用户会话的队列中,并在显示时删除它们。有两种方法可以做到这一点:
.emit
a callback function - 这是Socket.io为您提供的交付确认。确认传递后,您可以从用户的HTTP会话中删除通知队列。答案 1 :(得分:-1)
最简单的解决方案:使用onbeforeunload事件断开socket.io。
我使用HTTP调试器验证此事件在浏览器发出请求之前触发(至少在Chrome中),因此如果socket.io在此处断开连接,则不会收到任何针对以下页面的消息。
window.onbeforeunload = function() {
socket.disconnect();
};
我没有在多个浏览器中对此进行测试,因此它可能不是一个完美的解决方案,但它现在似乎解决了这个问题。