多个Socket.io应用程序进程导致每个客户端套接字反复连接和断开连接

时间:2019-01-30 08:48:06

标签: node.js socket.io haproxy

我正在使用Socket.io开发一个nodejs应用程序,我使用PM 2在单个过程中进行了测试,并且没有错误。然后转到生产环境(我们使用Google Cloud Compute Instance)。

我运行3个应用程序进程,并且iOS客户端连接到服务器。 顺便说一下,iOS客户端不保持套接字连接。它不会发送断开连接到服务器。但它已断开连接并重新连接到服务器。它不断发生。

我不确定服务器为何断开客户端连接。 如果您对此有任何暗示或答案,我将不胜感激。

3 个答案:

答案 0 :(得分:0)

这可能是因为请求最终位于不同的计算机上,而不是源于它们的计算机。

直接来自Socket.io Docs: Using Multiple Nodes

  

如果您打算在不同的进程或机器之间分配连接负载,则必须确保与特定会话ID相关联的请求连接到发起它们的进程。

您需要做什么:

  • 启用session affinity,又称为粘性会话
  • 如果要使用房间/命名空间,还需要使用集中式内存存储来跟踪名称空间信息,例如Redis/Redis Adapter

但是我建议您阅读我发布的文档,自从我上次实现这种东西以来,情况可能有所改变。

答案 1 :(得分:0)

默认情况下,socket.io客户端通过几个http请求“测试”到其服务器的连接。如果您有多个服务器请求,而这些初始的HTTP请求没有每次都到达相同的服务器,则socket.io connect将永远无法正确建立,也不会切换到webSocket,并且会继续尝试使用http轮询

有两种方法可以解决此问题。

  1. 您可以将客户端配置为仅假设webSocket协议有效。这将仅通过一个HTTP连接来启动连接,然后将其立即升级到webSocket协议(其中socket.io在其之上运行)。在socket.io中,这是使用初始连接指定的transport选项。

  2. 您可以将服务器基础结构配置为粘性,以便来自给定客户端的请求始终返回到完全相同的服务器。有多种方法可以执行此操作,具体取决于您的服务器体系结构以及服务器之间的负载平衡方式。

如果您的服务器将任何客户端状态保持在服务器本地(而不是在所有服务器都访问的共享数据库中),则您甚至需要断开连接并重新连接以返回同一服务器,并且需要保持粘性连接是您唯一的解决方案。您可以在socket.io网站here上阅读有关粘性会话的更多信息。

答案 2 :(得分:0)

感谢您的答复。

我终于弄清楚了这个问题。此问题是由Google Cloud Load Balancer中的后端服务的TTL引起的。默认的TTL是30秒,它使每个套接字连接都试图断开并重新连接。

所以我将值更新为3600s,然后可以保持连接。