WebSocket 笔记
- WebSocket 握手
客户端请求
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
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
一段被 base64 编码的内容,这段内容解码后是 the sample nonce
服务器返回
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
Sec-WebSocket-Protocol: chat
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
将客户端传来的 Sec-WebSocket-Key 加上固定的 GUID "258EAFA5-E914-47DA-95CA-C5AB0DC85B11" 之后用 SHA-1 (非对称加密)进行哈希,在采用 base64 编码。
这段 GUID 是固定的,所有的 websocket 都采用这个RFC 文档中说用它是因为 "unlikely to be used by network endpoints that do not understand the WebSocket Protocol"。
- 帧格式
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-------+-+-------------+-------------------------------+
|F|R|R|R| opcode|M| Payload len | Extended payload length |
|I|S|S|S| (4) |A| (7) | (16/64) |
|N|V|V|V| |S| | (if payload len==126/127) |
| |1|2|3| |K| | |
+-+-+-+-+-------+-+-------------+ - - - - - - - - - - - - - - - +
| Extended payload length continued, if payload len == 127 |
+ - - - - - - - - - - - - - - - +-------------------------------+
| |Masking-key, if MASK set to 1 |
+-------------------------------+-------------------------------+
| Masking-key (continued) | Payload Data |
+-------------------------------- - - - - - - - - - - - - - - - +
: Payload Data continued ... :
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
| Payload Data continued ... |
+---------------------------------------------------------------+
- 258EAFA5-E914-47DA-95CA-C5AB0DC85B11 将来自客户端的 Sec-WebSocket-Key 加上这个 GUID 然后 SHA-1 加密,之后进行 BASE64 编码,将结果作为 “Sec-WebSocket-Accept” 返回客户端。 GUID 一定是 258EAFA5-E914-47DA-95CA-C5AB0DC85B11 这个数。
- 一个单个帧的没有进行掩码的文本消息 0x81 0x05 0x48 0x65 0x6c 0x6c 0x6f(消息内容为 “Hello”)
0x81 1000 0001 未分片的消息只有一帧,所以FIN是1, 因为没有扩展RSV1 RSV2 RSV3 都是0 ,因为这是一个文本帧,所以opcode 是 1。
0x05 0000 01001 没有用掩码,所以 第一位 mask 是0,所以是 0000, hello 是 占 5个字节,所以是1001