Node.js 与 Socket.io - 长轮询失败并抛出“code”:1,“message”:“会话 ID 未知”响应

问题描述 投票:0回答:6

我不明白为什么移至 IIS7 服务器的 Node.js 应用程序现在失败了。我知道 IIS7 不支持 Web 套接字,但我的理解是,如果 Web 套接字不可用,socket.io 将退回到长轮询。因此,现在当用户尝试按下通常需要套接字或长轮询的特定按钮时,我会得到如下结果:

XHR finished loading: POST "https://localhost:817/socket.io/?EIO=2&transport=polling&t=1433777964357-6&sid=QWsESi0c9ih7WMWKAAAC".
GET https://localhost:817/socket.io/?EIO=2&transport=polling&t=1433777963494-5&sid=QWsESi0c9ih7WMWKAAAC 400 (Bad Request)
XHR finished loading: GET "https://localhost:817/socket.io/?EIO=2&transport=polling&t=1433777963494-5&sid=QWsESi0c9ih7WMWKAAAC".
OPTIONS https://localhost:817/socket.io/?EIO=2&transport=polling&t=1433777965127-7&sid=QWsESi0c9ih7WMWKAAAC 
XMLHttpRequest cannot load https://localhost:817/socket.io/?EIO=2&transport=polling&t=1433777965127-7&sid=QWsESi0c9ih7WMWKAAAC. Invalid HTTP status code 400

当我单击 GET 或 XMLHttpRequest 时,我可以看到响应是

"code":1,"message":"Session ID unknown"
,我不明白,因为我可以看到 SID。当我单击列出的选项失败代码时,我发现问题来自 Request.prototype.create,即 xhr 发送:

xhr.send(this.data);

有人知道是什么原因造成这些事情吗?

如有任何澄清,我们将不胜感激!

非常感谢!

javascript node.js sockets iis-7 long-polling
6个回答
35
投票

对于socket.io v2.0.3(js客户端),当您在客户端使用socket.io时,客户端socket.io会进行一些网络调用,如下所示:

  1. 当调用 io.connect() 时,socket.io 库会调用服务器,如下所示

    ?EIO=3&transport=polling&t=LqtOnHh
    ,

    服务器响应类似

    "90:0{"sid":"pcJM_AEZirrJT-DuAAUy","upgrades[], "pingInterval":3600000,"pingTimeout":3600000}2:40"

    服务器在服务器端生成一个套接字对象并发送它 id 返回给客户端。

  2. 此客户端再次调用服务器后,类似于

?EIO=3&transport=polling&t=LqtR6Rn&sid=0JFGcEFNdrS-XBZeAAXM

这是客户端对服务器进行的长轮询调用,如果您在这里看到它正在传递在上面的第一次调用中收到的 sessionId,如果调用转到生成该 sessionId 的同一节点,则该节点会识别套接字连接已提出请求并做出响应。

但是在负载均衡器后面,调用可能会转到未生成此 sessionId 的其他节点,在这种情况下,该节点将无法识别进行调用的 sessionId,因此会以

{"code":1,"message":"Session ID unknown"}

进行响应

如果长时间轮询未得到答复或超时,您也会看到此错误。


13
投票

在我的项目中,我尝试将

transport
选项添加为
websocket
,并且不再出现错误。

io.connect(url, {
   "transports": ['websocket']
})

支持 IE 和其他旧浏览器将是一个问题,因为它们不支持本机 websockets,如果应用程序浏览器兼容性不是问题,这似乎是一个解决方案。


9
投票

对我来说,它是使用 nginx ssl http2,并且是轮询,所以好的配置是:

 const ioSocket = io('', {
      // Send auth token on connection, you will need to DI the Auth service above
      // 'query': 'token=' + Auth.getToken()
      path: '/socket.io',
      transports: ['websocket'],
      secure: true,
    });

2
投票

如果你使用 Socket.io-Redis 那么它看起来就像 Socket.io 的错误跟踪器中描述的情况:

https://github.com/socketio/socket.io/issues/1739#issuecomment-64244359


1
投票

最近在socket.io上遇到了同样的错误:

{"code":1,"message":"Session ID unknown"}
用于网络套接字连接,尽管设置不同(nginx +乘客+nodejs)。该问题是我的 NodeJS 应用程序中从 NodeJS 到 Redis 的连接中断。因此,一旦 Redis 正确启动(这是 IP 绑定问题),socket.io 就开始通过 Web 套接字正常通信。如果您遇到同样的问题,请检查您的 NodeJs 应用程序是否正常工作(例如,它连接到所有必需的资源)


0
投票

据我所知,您需要启用粘性会话才能使长轮询正常工作。 您可以在此处阅读有关如何执行此操作的信息 socket io 文档

或者你可以在套接字设置中禁用轮询,如@saeta所述 在这个答案中

© www.soinside.com 2019 - 2024. All rights reserved.