【问题标题】:SocketIO websocket handshake is different from what is described by RFC 6455SocketIO websocket 握手与 RFC 6455 所描述的不同
【发布时间】:2015-09-25 03:10:46
【问题描述】:

我正在尝试了解有关 websockets 协议的更多信息。根据 RFC 6455,此协议的步骤是握手,它以 HTTP 升级请求开始:

 GET /chat HTTP/1.1
    Host: server.example.com
    Upgrade: websocket
    Connection: Upgrade
    Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
    Origin: http://example.com
    Sec-WebSocket-Protocol: chat, superchat
    Sec-WebSocket-Version: 13 

服务器用 HTTP 交换协议消息响应:

HTTP/1.1 101 Switching Protocols
    Upgrade: websocket
    Connection: Upgrade
    Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
    Sec-WebSocket-Protocol: chat

我尝试使用基于socketIO(nodeJS websockets库)的简单程序来观察这一点。捕获流量后,我注意到客户端发送给服务器的第一条消息是:

GET /socket.io/?EIO=3&transport=polling&t=1443149751115-0 HTTP/1.1
Host: localhost
Connection: keep-alive
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/537.36            (KHTML, like Gecko) Chrome/45.0.2454.85 Safari/537.36
Origin: null
Accept: */*
Accept-Encoding: gzip, deflate, sdch
Accept-Language: en-US,en;q=0.8

服务器响应的:

HTTP/1.1 200 OK
Content-Type: application/octet-stream
Content-Length: 101
Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: null
Set-Cookie: io=3Z_TCqv9LKKXcWCjAAAD
Date: Fri, 25 Sep 2015 02:55:51 GMT
Connection: keep-alive

....0{"sid":"3Z_TCqv9LKKXcWCjAAAD","upgrades":    ["websocket"],"pingInterval":25000,"pingTimeout":60000}

是 SocketIO 没有遵循 websockets 的 RFC 还是我遗漏了什么?

【问题讨论】:

    标签: websocket socket.io


    【解决方案1】:

    socket.io 在连接到 webSocket 之前有它自己的连接管理东西,它允许它协商它实际上要与服务器建立哪种类型的连接,并允许它向客户端发送一些配置选项。如果您尝试研究普通的 webSocket,这会让您感到困惑。

    socket.io 是 webSocket 之上的附加协议。它最终会在下面使用一个标准的 webSocket,但它会有额外的东西。如果你继续关注 socket.io 连接,你最终会看到一个标准的 webSocket 连接。

    我建议您首先从您的客户端(无 socket.io)建立一个普通的 webSocket 连接并研究该网络跟踪。

    【讨论】:

    • 这些差异是否记录在任何地方?
    • @SivaDotRender - 除了原始实现者自己编写的内容外,还有许多其他语言的 socket.io 实现。我不确定最好的文档在哪里,但有一些 herehere
    【解决方案2】:

    在 js 客户端,使用 websocket 传输连接到服务器。这将启用与 RFC 6455 相同的默认 websocket 机制。

    var socket = io.connect('http://localhost:8080', {
       transports: [
         'websocket',
         'polling'
       ]
    });
    

    【讨论】:

    • 谢谢,这就是我要找的东西!
    【解决方案3】:

    我相信你是对的,socket.io 不遵守 RFC 6455。为了测试这一点,我在 ubuntu 虚拟机中运行了一个 javascript 服务器,并在主机中 ubuntu 成功地与服务器进行了 socket.io 交互。我用sudo tcpdump -i vboxnet1 -w dump.out捕获了网络流量,并用wireshark分析了结果。

    socket.io 握手就像原始海报所代表的那样,整个脚本成功完成(客户端接收 websocket 消息),而 tcpdump 从未显示带有升级标头的 HTTP 请求,如 https://www.rfc-editor.org/rfc/rfc6455#section-4.1

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多