socket.io在客户端闲置时会断开连接

10

我有一个生产应用程序,使用socket.io (node.js后端)来向所有已登录客户端分发消息。许多用户经常从socket.io服务器断开连接。通常客户端的使用情况是整个工作日都保持Web应用程序处于打开状态。在一天的大部分时间里,应用程序处于空闲状态,但是应用程序仍然处于打开状态——直到socket.io连接丢失,然后应用程序将被退出。

是否有任何方法可以使连接更可靠,以便我的用户不会经常失去与socket.io服务器的连接?


客户端使用什么类型的计算机?移动设备?平板电脑?笔记本电脑?台式机?现在许多设备在长时间不活动后会进入省电模式,这会导致连接被关闭。 - jfriend00
100%的桌面设备,主要使用现代浏览器IE 9或更高版本(大部分情况下),Chrome和Fire Fox。连接问题似乎不在任何特定的浏览器上。 - EToreo
任何桌面电脑都有让CPU进入睡眠模式的功能吗? - jfriend00
我希望我能确定,但我真的怀疑。我已经在没有睡眠模式(操作系统或CPU)的计算机上复制了它。 - EToreo
您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - jfriend00
这正是我的想法,我很难想出一个解决方法甚至调试它... - EToreo
2个回答

8
看起来我们能够在这里为您提供一些调试建议,以便您更多地了解问题的原因。以下是需要查看的列表:
  1. 确保socket.io已配置为自动重新连接。 在最新版本的socket.io中,自动重新连接默认为打开状态,但您可能需要验证是否有任何代码将其关闭。

  2. 确保客户端未休眠,以使所有网络连接变得不活跃并断开连接。

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

  4. 由于您提到您可以重现此情况,因此您想要知道套接字是如何关闭的(客户端端还是服务器端引发)。 收集有关此信息的一种方法是在客户端上安装网络分析器,以便您可以实际上观看每个发送到/从您的客户端的数据包。 有许多不同的分析器,其中许多是免费的。 我个人使用过Fiddler,但我经常听到人们谈论WireShark。 您想要查看的是当客户端失去连接时网络上会发生什么。 客户端是否决定发送关闭套接字数据包? 客户端是否收到来自某个人的关闭套接字数据包? 连接断开时网络上发生了什么。


Chrome调试器中的webSocket网络视图

webSocket network view in Chrome Debugger


嗨,当套接字自行断开连接后,我的代码会停止工作,直到我刷新应用程序。 - kd12345
@kd12345 - 普通的WebSockets没有自动重新连接逻辑,因此如果您想要重新连接功能,则必须自己构建它或使用socket.io,它在WebSocket之上构建了自动重新连接逻辑。 - jfriend00
我实际上正在使用socket.io,但由于某种原因,当它断开连接时,socket会破坏我的nodejs服务器。https://dev59.com/b3sPtIcB2Jgan1zn_liK - kd12345

1
最有可能的原因是一端由于不活动而关闭了WebSocket。这通常由负载均衡器执行,但也可能是其他罪魁祸首。解决此问题的方法是定期向每个客户端发送消息(我使用30秒,但根据问题的情况,您可以将其设置得更高)。这将防止它看起来处于非活动状态,从而被关闭。

6
socket.io已经自动发送心跳消息来保持连接并检测是否已断开,因此无需发送自己的消息。似乎有其他原因(而非不活动)导致连接被关闭。 - jfriend00
@jfriend00 我试了你的方法,但是在移动浏览器上,当页面不在焦点状态下,我的 Socket IO 会在 30 秒后出现 ping 超时的问题。我甚至改变了 Socket IO 的超时设置,但没有什么区别。我还尝试了发送自己的心跳事件,但仍然在 30 秒后超时。按照您的建议,我做了这个,但是当页面不在焦点状态下,Socket IO 仍然会超时,请看看是否能提供帮助 https://dev59.com/67fna4cB1Zd3GeqPpUFW - Faizan
1
@Faizan - 我不知道你为什么要回答这个其他的问题。移动浏览器可能会关闭不在前台的页面以节省电池电量。在移动浏览器中保持webSocket活动状态可能无法解决。 - jfriend00

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接