Javascript Websockets在页面卸载时断开连接

Posted

技术标签:

【中文标题】Javascript Websockets在页面卸载时断开连接【英文标题】:Javascript Websockets Disconnect on Page Unload 【发布时间】:2021-12-04 06:58:57 【问题描述】:

我正在使用 python 烧瓶和网络技术构建一个在线游戏,该技术使用网络套接字来允许游戏实时运行。游戏的一页是一个大厅,所有当前玩家都显示在上面。如果用户从游戏中断开连接,他们当然应该从大厅列表中删除。

我认为,为了让用户迅速从列表中消失,客户端的浏览器需要手动发送断开连接,执行 socket.disconnect() 或在页面卸载时发送另一个自定义事件。

不幸的是,我似乎无法使用onunload 事件运行它 - 它在页面加载时运行,而不是在您离开页面时运行。我也找不到使用 onbeforeunload 事件的方法,因为我已经在使用它来显示确认弹出窗口。

对此的任何建议将不胜感激!提前致谢!

我的客户端代码:

    window.addEventListener("beforeunload", function(event) if (!intentionalForward) event.preventDefault(); event.returnValue = " ");
    window.addEventListener("unload", function ()  socket.emit("test","testing unload event"); );

【问题讨论】:

【参考方案1】:

发生的情况是,您调用 socket.emit 并将该调用的结果作为事件侦听器分配给 unload 事件。你应该使用这样的闭包函数:

window.addEventListener("unload", function()  socket.emit("test","testing unload event"); );

【讨论】:

除此之外,beforeunloadunload 可能不可靠,并且浏览器的处理方式不同。最重要的是,您还应该通过每隔一段时间从服务器->客户端发送“ping”请求来检查客户端是否从服务器连接,例如。 60 秒并等待客户端响应,然后在 x 次 ping 后跟踪谁没有响应。 感谢您回复我,不幸的是这并没有什么不同。 :( 确实,我在测试的早期就已经把它写成这样了,但我认为至少它做了 something 就像我写的那样 - 现在我知道为什么了。 @DoubleJG 这将始终是后备选项,但我希望它在大多数情况下比使用 ping 实现的响应更快。我在我们曾经在学校玩的一个名为 Kahoot 的网站上对我的游戏进行建模。我对该网站的调查表明,如果您正常关闭浏览器,那么您将立即与游戏列表断开连接,但如果您将其杀死,例如使用任务管理器,则需要几秒钟才能将您的名字从其他人的列表中删除。 【参考方案2】:

通过强制客户端使用 websocket 传输连接(通过将transports: ["websocket"] 标志添加到我的io.connect 函数),我设法使其正常工作。这意味着断开事件现在可以在服务器上运行。

注意从这一点开始,我需要安装和使用 gunicorn,因为烧瓶开发服务器不支持 websocket。

【讨论】:

以上是关于Javascript Websockets在页面卸载时断开连接的主要内容,如果未能解决你的问题,请参考以下文章

关于 Websockets

解读 JavaScript 之深入探索 WebSockets 和 HTTP/2

使用 tornado websockets 传递消息

结合 JavaScript、Websockets 和 Java

如何为频繁的数据库更新编写 Websockets/AJAX 代码?或者有没有更好的方法?

JavaScript 和 WebSockets:使用特定协议