带有Socket.io的Node.js - Long Polling失败并抛出"code":1,"message":"Session ID unknown"响应

mar*_*rio 9 javascript sockets iis-7 long-polling node.js

我坚持为什么移动到IIS7服务器的nod​​e.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
Run Code Online (Sandbox Code Playgroud)

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

xhr.send(this.data);
Run Code Online (Sandbox Code Playgroud)

有谁知道可能导致这些事情的原因是什么?

任何澄清将不胜感激!

非常感谢!

Sha*_*ain 8

对于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的同一节点,则该节点识别为哪个socket连接请求已经完成并作出响应.

    但是在ELB后面,调用可能会转到其他未生成此sessioId的节点,在这种情况下,节点将无法识别为其进行调用的sessionId,因此会响应 {"code":1,"message":"Session ID unknown"}

如果长轮询没有得到应答或超时,您也会看到此错误.

  • 您需要保持负载均衡器的粘性 (3认同)
  • 阅读有关粘性的内容,您将了解,唯一的解决方法是您不使用 socket.io 库中的轮询,而只使用其中的 websockets 配置 (3认同)

slo*_*nzo 6

在我的项目中,我尝试将transport选项添加为a,websocket并且不再出现错误。

io.connect(url, {
   "transports": ['websocket']
})
Run Code Online (Sandbox Code Playgroud)

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

  • 我在 chrome 中遇到了这个问题。过去 1 天一直在努力解决这个问题。非常感谢您的解决方案。 (2认同)

Pat*_*zlo 5

对我来说,它是使用 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,
    });
Run Code Online (Sandbox Code Playgroud)


ant*_*ono 2

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

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