SocketIO的WebSocket握手与RFC 6455所描述的不同。

6

我希望学习更多关于WebSocket协议的知识。根据RFC 6455,该协议的步骤是握手,它开始于HTTP Upgrade请求:

 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的简单程序尝试观察这个过程(socketIO是nodeJS的websocket库)。在捕获到流量后,我注意到客户端发送给服务器的第一条消息是:

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标准,还是我有所遗漏?
3个回答

8

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

socket.io是在WebSocket之上的一个额外协议。它最终将使用标准WebSocket,但它会在其周围添加其他内容。如果您继续跟踪socket.io连接,您最终将看到一个标准的WebSocket连接。

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


这些差异在任何地方都有记录吗? - SivaDotRender
@SivaDotRender - 这是有记录可查的,除了最初的实现者自己编写的socket.io之外,还有许多其他语言的实现。我不确定最好的文档在哪里,但是这里有一些资料(https://github.com/socketio/engine.io-protocol)和(https://github.com/socketio/socket.io-protocol)。 - jfriend00

4

在JS客户端,使用WebSocket传输连接到服务器。这使默认WebSocket机制与RFC 6455相同。

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

1
谢谢,这正是我在寻找的! - csblo

1
我相信你是正确的,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所描述的那样。

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