简介

  1. WebSocket是一种传输层使用TCP协议的应用层协议,允许全双工通信。主要使用场景是WebServer向WebClient(如浏览器)推送数据。

握手过程

  1. 在客户端与服务端进行双工通信之前,需要完成握手过程。握手过程如下所示:
    1. 由WebClient向WebServer发送一个包
    GET / HTTP/1.1
    Host: 192.168.225.75:9000
    Connection: Upgrade
    Pragma: no-cache
    Cache-Control: no-cache
    User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36
    Upgrade: websocket
    Origin: null
    Sec-WebSocket-Version: 13
    Accept-Encoding: gzip, deflate
    Accept-Language: zh-CN,zh;q=0.9
    Sec-WebSocket-Key: gx4B0y0bSxU3VStAmlmGwQ==
    Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits
    
    
    1. WebServer响应客户端
    HTTP/1.1 101 Switching Protocols
    Upgrade: websocket
    Connection: Upgrade
    Sec-WebSocket-Accept: JMxIno2O959kcOwylYIigQmRapw=
    
    
  2. 注意到WebServer响应的报文中,存在一个Sec-WebSocket-Accept字段,这个字段表明服务端会初始化一个WebSocket连接。其计算方法如下:
    1. 将Sec-WebSocket-Key拼接"258EAFA5-E914-47DA-95CA-C5AB0DC85B11"形成新字符串str
    2. 进行hash计算:SHA1(str)
    3. base64编码:base64_encode(SHA1(str))

数据传输

在WebSocket协议中,使用数据帧进行数据的传输

1.数据帧格式
  1. 数据帧格式如下所示:
  2. Payload len字段:表示Payload Data的长度
    1. 其值为0-125,则表示Payload Data的长度
    2. 其值为126,则接下来的两个字节表示Payload Data的长度
    3. 其值为127,则接下来的8个字节表示Payload Data的长度
  3. MASK字段:决定是否对Payload Data进行掩码操作,设置成1表示会使用Masking-key四字节的值对Payload Data进行掩码操作。在客户端发往服务端的数据帧中,这个字段的值必须为1,即Payload Data必须进行掩码操作 掩码操作伪码如下所示:
Payload Data[length]
Masking-key = {0x11, 0x22, 0x33, 0x44};
for (int i = 0; i < LENGTH; ++i) {
    Payload Data[i] ^= Masking-key[i % 4]
}
  1. FIN字段:表示当前数据帧是否为消息的最后一个切片

关闭

关闭WebSocket连接,需要将FIN字段设置为1

相对HTTP协议的优点

  1. HTTP协议每次发送数据需要携带请求头或者响应头,而WebSocket协议包头长度支持可扩展,使用可变长大小表示包体的大小,如7bit,7+16bit,7+64bit。因此能够提升带宽利用率,携带比例更多的有效数据
  2. WebSocket协议支持双向通信,并且保持连接状态

参考:WebSocket rfc6455文档