socket.io 在空闲时断开客户端的连接

Posted

技术标签:

【中文标题】socket.io 在空闲时断开客户端的连接【英文标题】:socket.io disconnects clients when idle 【发布时间】:2015-07-28 14:51:51 【问题描述】:

我有一个生产应用程序,它使用 socket.io(node.js 后端)将消息分发给所有登录的客户端。我的许多用户都遇到了与 socket.io 服务器的断开连接。客户端的正常用例是让 Web 应用程序在整个工作日保持打开状态。工作日中应用程序的大部分时间都处于空闲状态,但应用程序仍处于打开状态 - 直到 socket.io 连接丢失,然后应用程序将它们踢出。

有什么方法可以使连接更可靠,这样我的用户就不会经常失去与 socket.io 服务器的连接?

【问题讨论】:

客户使用什么样的电脑?移动设备?平板电脑?笔记本电脑?台式机?如今,许多设备会在设备未处于活动状态时进入省电模式,这将导致连接关闭。 100% 桌面,主要是现代浏览器 IE 9 或更高版本(大部分)、Chrome 和 Fire Fox。连接问题似乎不在任何特定浏览器上。 是否有任何桌面具有 CPU 进入睡眠的睡眠模式? 我希望我能确定,但​​老实说我对此表示怀疑。我在没有睡眠模式(操作系统或 CPU)的计算机上复制了它。 如果不是本地计算机终止连接,也不是服务器,那么它一定是客户端和服务器之间路径中的某个网络基础设施。如果 socket.io 配置正确并且客户端没有休眠,它应该在连接断开时重新连接。 【参考方案1】:

看来,我们在这里所能做的就是给您一些调试建议,以便您了解更多关于导致问题的原因。所以,这里列出了一些需要研究的事项。

    确保将 socket.io 配置为自动重新连接。在最新版本的 socket.io 中,自动重新连接默认为开启,但您可能需要验证没有任何代码将其关闭。

    确保客户端不会进入休眠状态,这样所有网络连接都将变为非活动状态并断开连接。

    在正常工作的客户端(断开连接之前)中,使用 Chrome 调试器、网络选项卡、webSockets 子选项卡来验证您是否可以看到客户端和服务器之间的常规 ping 消息。您必须打开调试窗口,进入网络选项卡,然后在打开该调试窗口的情况下刷新您的网页以开始查看网络活动。您应该会看到一个看起来很时髦的 URL,其中包含 ?EIO=3&transport=websocket&sid=xxxxxxxxxxxx。点击那个。然后单击“框架”子标签。此时,您可以查看正在发送的单个 websocket 数据包。您应该每隔一段时间看到长度为 1 的小数据包(这些是 ping 和 pong 保持活动数据包)。下面有一个示例屏幕截图,显示了您要查找的内容。如果您没有看到这些保持活动的数据包,那么您需要解决它们不存在的原因(可能是一些 socket.io 配置或版本问题)。

    既然您提到可以重现这种情况,您想知道的一件事是套接字是如何关闭的(客户端启动或服务器端启动)。收集这方面信息的一种方法是在您的客户端上安装网络分析器,这样您就可以从字面上观察通过网络传入/传出客户端的每个数据包。有许多不同的分析仪,而且很多都是免费的。我个人使用过 Fiddler,但我经常听到人们谈论 WireShark。您想看到的正是当客户端失去连接时网络上发生的情况。客户端是否决定发送关闭套接字数据包?客户端是否收到来自某人的关闭套接字数据包?连接断开时网络上发生的情况。


Chrome 调试器中的 webSocket 网络视图

【讨论】:

【参考方案2】:

最可能的原因是由于不活动而关闭 WebSocket 的一端。这通常由负载平衡器完成,但可能还有其他罪魁祸首。解决此问题的方法是简单地每隔一段时间(我使用 30 秒,但根据问题您可能会更高)向每个客户发送一条消息。这将防止它看起来处于非活动状态并因此被关闭。

【讨论】:

socket.io 已经发出自动心跳消息以保持连接打开并检测连接何时断开。因此,无需发送您自己的消息。似乎有其他原因(不活动除外)导致连接关闭。 @jfriend00 我试过你的,但是当页面不在移动浏览器上的焦点时,我的套接字 io 在 30 秒后 ping 超时,我什至更改了套接字 io 超时设置,但它没有有什么不同,我什至尝试发出我自己的心跳事件,但它仍然在 30 秒后超时,按照你的建议我这样做了,但是当页面不在 foucs 中时,socket io 仍然超时,请检查你是否可以帮助***.com/questions/58667207/…跨度> @Faizan - 我不知道你为什么要回复这个其他答案。移动浏览器可能会关闭不在前台的页面以节省电量。您可能无法在移动浏览器中保持 webSocket 处于活动状态。

以上是关于socket.io 在空闲时断开客户端的连接的主要内容,如果未能解决你的问题,请参考以下文章

如何从客户端断开和重新连接 socket.io?

socket.io 服务器在注册客户端断开连接时非常延迟

即使在他们断开 nodeJS socket.io 之后也记住一个客户

在 NestJS 中连接后,Socket.io 客户端正在断开连接

socket.io 客户端在长 Node.js 函数中自动断开连接

使用 Socket.io 检测(客户端)连接断开