websocket协议学习整理

websocket协议报文头格式:

                                  websocket协议学习整理

分片的好处之一:是多用于多路复用,一个逻辑通道上的一个大消息独占输出通道是不可取的,因此多路复用需要可以分割消息为更小的的分段(分片)来更好的共享输出通道。

FIN字段(1bit):指示这个websocket消息的最后片段(设置为1时),是第一个片段(没有分片时第一个片段也是最后一个片段)也可能是最后一个片段(分片时的最后一个片段)。

RSV1,RSV2,RSV3(每一位一bit):

必须是0,除非一个扩展协商为非零值定义含义(也就是两端协商好的一个值)。如果一端收到一个非零值且没有协商的扩展定义这个非零值的含义,接收端必须以报文处理失败告终,并发送close报文给对端,断开websocket连接。

opcode(4bit):此字段标识着这个websocket报文的报文数据类型,占4bit,常用数据含义如下:

0x0:代表一个继续帧

0x1:文本数据帧

0x2:二进制数据帧

0x3-0x7:保留用于未来的非控制帧

0x8:close帧代表链接关闭

0x9:代表ping报文

0xA:代表pong报文

0xB-F:保留用于未来的控制帧

控制帧类型说明:

ping/pang报文: 一个端点在收到对端发过来的ping报文时,必须在响应中发送一个ping帧,除非他早已接收到一个close帧。它应尽可能快的以pong帧作为响应。这也就是控制帧要求时效性比较高的体现。

一个端点可以在链接建立之后和链接关闭之前的任何时刻发送一个ping帧。

注:一个ping帧既可以充当一个keepalive,也可以作为验证远程端点仍可响应的手段。实际应用的时候,一般ping/pong报文用于刷中间链路net表项,防止net表项老化的一个手段。一般发送方发送ping报文之后不关心是否收到pong报文响应。只是定时发送而已。

close帧:

close报文用于关闭连接,可以包含内容体的应用数据部分,用于指示一个关闭的原因;如果有内容体,内容体的头两个字节必须是2个字节的无符号整数(网络序),代表断开链接的状态码,具体的状态码含义可以参照协议的讲解。内容体(playload数据部分)紧跟着2个字节状态码后面的数据如果有的话,包含的是UTF-8编码的reason值,---》字符串。reason消息,

也可以不包含内容体,即payload的长度为0,有种情况是:某一端点在关闭连接时发送给对端的close报文不带报文体内容。只有websocket头。

如果一个端点在接收到一个关闭帧且先前没有发送一个关闭帧,端点必须在响应中发送一个关闭帧。(当在响应中发送关闭帧时,端点通常回送它接收到的状态码填充到响应的close帧当中)。它应该根据实际情况尽快这样做。

在应用发送关闭帧之后,必须不发送任何更多的数据帧。多线程操作时,可能保证不了这一点,因为在关闭连接的的同时,其他线程可能继续发送数据,因为是并行的。端点可以延迟发送关闭帧,直到它当前消息发送完成。例如如果一个分片消息的大多数已经发送了,端点可以发送剩余的片段在发送一个关闭帧之前。但是,不保证一个已经发送关闭帧的端点将继续处理数据。

分片情况说明

websocket 报文没有分片时:

FIN:1                                          opcode:非0(真实数据的opcode)

非分片报文,FIN为1即是第一片也是最后一片。

注:控制帧可以被注入到一个分片消息的中间,控制帧本身不能被分片。所以一般只有非控制帧进行分片操作(0x1、0x2)

websocket 报文分片时:

1:首片:

FIN:0                                             opcode:非0(真实数据的opcode)

2:中间片:

FIN:0                                             opcode:0

2:中间片:

FIN:1                                             opcode:0

分片报文,FIN为1即分片的最后一片。

也就是说:分片报文的只有首片才会填写opcode,FIn字段为1标识着分片报文的最后一片,中间片FIn字段和opcode都为0.

几条原则:

1:控制帧可以被注入到一个分片消息的中间发送出去,发送给对端,控制帧本身必须不能被分割(即控制帧本身不能被分片)。

2:任意一个端点(链接的两端: 客户端和服务器端)必须能处理一个分片消息中间的控制帧。

如果控制帧不能被插入一组分片报文中间发送出去,或者任意的一个端点,不能处理分片消息中间的控制帧,那么控制帧只能按照顺序发送出去,不能插入分片消息中间,待发送的控制帧就必须等待前面带发送 的分片消息发送完成,才可以发送。此时如果遇到一组特别大的分片消息发送,那么后续的控制帧发送就会造成延时问题产生。控制帧的时效性比较高,比如close报文,要求立刻断开链接,但是消息延时,造成控制帧延时,就不合理。所以有以上两点需要注意一下。

3:消息分片要按发送者发送的顺序交付给收件人(不能乱序,要保序)

4:分片的一个消息必须不能与片段中的另一个消息交替,除非已经协商好了一个解释交替的扩展。

5:一个发送者可以为非控制消息创建任何大小的片段(发送方主动分片并自定义分片大小)

6:客户端和服务器必须支持结束分片消息和非分片消息。