24

websocket协议解读 | Anfield

 4 years ago
source link: http://ai-freedom.org/2020/03/05/websocket-protocol/?
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

websocket协议解读

发表于 2020-03-05

| 分类于 协议

|

| 阅读次数:

websocket协议

RFC 6455

消息结构:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
 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 ... |
+---------------------------------------------------------------+

FIN 1bit

消息的最后一帧 (第一帧也可以是最后一帧)

RSV1,RSV2,RSV3 每个1bit

必须为0,除非双方协商定义了非零值的扩展,如果非零且未协商定义,则收到的终端必须断开WebSocket连接

Opcode 4bits

定义了交互的携带数据, 如果收到位置的opcode,收到的终端必须断开WebSocket连接

  • %x0 附加数据帧
  • %x1 文本数据帧
  • %x2 二进制数据帧
  • %x3-7 保留的opcode,用于非控制帧
  • %x8 连接关闭
  • %x9 ping
  • %xA pong
  • %xB-F 保留的opcode,用于控制帧

Mask 1bit

用于标识Playload Data是否经过掩码处理。如果是1,Masking-key域的数据就是掩码密钥,用于解码Payload Data。客户端发出的数据帧需要进行掩码处理,所以要设置为1。

Payload length 7bits,7+16bits,7+64bits

PayloadData的长度解释 (以字节为单位)。

  • 如果其值在0-125,则是payload的真实长度。
  • 如果值是126,则后面2个字节形成的16位无符号整型数的值是payload的真实长度。注意,网络字节序,需要转换。
  • 如果值是127,则后面8个字节形成的64位无符号整型数的值是payload的真实长度。注意,网络字节序,需要转换。
    长度表示遵循一个原则,用最少的字节表示长度(我理解是尽量减少不必要的传输)。举例说,payload真实长度是124,在0-125之间,必须用前7位表示;不允许长度1是126或127,然后长度2是124,这样违反原则。
    Payload长度是ExtensionData长度与ApplicationData长度之和。ExtensionData长度可能是0,这种情况下,Payload长度即是ApplicationData长度。

Masking-key 0 or 4 bytes

WebSocket协议规定数据通过帧序列传输,特点如下:

  • 客户端必须对其发送到服务器的所有帧进行掩码处理(32位的值)。
  • 服务器一旦收到无掩码帧,将关闭连接。服务器可能发送一个状态码是1002(表示协议错误)的Close帧。
  • 服务器发送客户端的数据帧不做掩码处理,一旦客户端发现经过掩码处理的帧,将关闭连接。客户端可能使用状态码1002。

Payload data (x+y)bytes

Payload data 被定义为扩展数据(Extension Data)加上应用数据(Application Data)

Extension Data x bytes

如果客户端与服务端之间没有特殊约定,那么扩展数据的长度始终为0,任何的扩展都必须指定扩展数据的长度,或者长度的计算方式,以及在握手时如何确定正确的握手方式。如果存在扩展数据,则扩展数据就会包括在负载数据的长度之内

Application Data y bytes

任意的应用数据,放在扩展数据之后,应用数据的长度=负载数据的长度-扩展数据的长度。

分片目的是发送长度未知的消息。如果不分片发送,即一帧,就需要缓存整个消息,计算其长度,构建frame并发送;使用分片的话,可使用一个大小合适的buffer,用消息内容填充buffer,填满即发送出去。
分片规则:

  1. 一个未分片的消息只有一帧(FIN为1,opcode非0)
  2. 一个分片的消息由起始帧(FIN为0,opcode非0),若干(0个或多个)帧(FIN为0,opcode为0),结束帧(FIN为1,opcode为0)。
  3. 控制帧可以出现在分片消息中间,但控制帧本身不允许分片。
  4. 分片消息必须按次序逐帧发送。
  5. 如果未协商扩展的情况下,两个分片消息的帧之间不允许交错。
  6. 能够处理存在于分片消息帧之间的控制帧
  7. 发送端为非控制消息构建长度任意的分片
  8. client和server兼容接收分片消息与非分片消息
  9. 控制帧不允许分片,中间媒介不允许改变分片结构(即为控制帧分片)
  10. 如果使用保留位,中间媒介不知道其值表示的含义,那么中间媒介不允许改变消息的分片结构
  11. 如果协商扩展,中间媒介不知道,那么中间媒介不允许改变消息的分片结构,同样地,如果中间媒介不了解一个连接的握手信息,也不允许改变该连接的消息的分片结构
  12. 由于上述规则,一个消息的所有分片是同一数据类型(由第一个分片的opcode定义)的数据。因为控制帧不允许分片,所以一个消息的所有分片的数据类型是文本、二进制、opcode保留类型中的一种。
    需要注意的是,如果控制帧不允许夹杂在一个消息的分片之间,延迟会较大,比如说当前正在传输一个较大的消息,此时的ping必须等待消息传输完成,才能发送出去,会导致较大的延迟。为了避
    免类似问题,需要允许控制帧夹杂在消息分片之间。

用于控制WebSocket协议的通信状态,控制帧可以出现在分片消息中,但是其长度必须小于等于125,因为控制帧不允许分片。

  • 0x8 close, close帧会有不同的值,表示连接关闭的原因,正常关闭状态码为1000,应用也可以自行扩展,具体对照关系见close码与原因对照表
  • 0x9 ping
  • 0xA pong
  • 0xB-F 保留
  • 0x1 text 文本数据
  • 0x2 binary 二进制数据
gerrard wechat
微信扫一扫,订阅我的博客动态^_^
您的支持将鼓励我继续创作!

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK