原文链接: 认识websocket协议 - Tansoz 探索者
首先WebSocket是在TCP上搭建出来的,所以可以保持着一直连接的状态,除非某一方断开连接。
首先我先说说服务端和客户端(多为浏览器)一开始连接,由客户端 js 发起连接请求,HTTP 协议的请求会发出像下面例子这样的一个请求头。
但服务器收到 Upgrade 信息后,如果服务器支持。
那么服务端会读取请求头部的 Sec-WebSocket-Key 的值,并且将 Sec-WebSocket-Key 和 字符串 "258EAFA5-E914-47DA-95CA-C5AB0DC85B11" 通过sha1 摘要算法得到 Sec-WebSocket-Accept 的值,
然后响应头状态码会是 101 Switching Protocols ,下面是一个示例响应头。
到了这里已经把发起请求然后保存连接的过程说完了。接下来就是开始说 WebSocket 协议的结构了。
FIN
大小: 1bit
意思: 当FIN值为 0 的时候代表,消息还没完整,只是其中的一个数据包;当值为 1 的时候代表这段消息已经完全发送了。
RSV 1 / 2 / 3
大小: 1bit
意思: 这个默认为 0 ,如果一定要启用,就得和服务端协商好,才具有意义。
OPCODE
大小: 4bit
意思: 该数据包类型
0 代表数据不完整,这只是其中的一个,不是最后的那个数据包。(Continuation Frame)
1 代表数据包内容的类型为 文本类型(Text Frame)
2 代表数据内容类型为 二进制类型 (Binary Frame)
8 代表连接断开 (Connection Close Frame)
9 和 10 是心跳检测,如果服务端发出 Ping Frame 那么客户端就得发回 Pong Frame ,如果服务端接受不到 Pong Frame 就代表客户端可能已经下线了。
0 - 15 中现在除了这 6 个,都为保留帧。
MASK
大小: 1bit
意思: 掩码是否开启
1 代表开启
0 代表关闭
Payload len
大小: 7bit(默认)
意思: 内容数据(Payload Data)的长度
Masking-key
大小: 4Byte(默认)
意思: 掩码数据,如果 Mask 为 1 就启用,否则不启用
Payload Data
大小: 0-127Byte(默认,根据Payload len的值决定长度)
意思: 存放数据的地方
PS: 如果Mask为1时,Payload Data 就需要通过 Mask 掩码加密。下面是一个 Golang 版本的加密代码。
for i := 0; i < datalen; i {
m := markingkeys[i%4]
data[i] = msg[i] ^ m
}