websocket协议详解

近来项目中使用websocket,于是来研究一番。websocket传输协议有两个部分,握手和数据传输

握手

GET / HTTP/1.1
HOST: <IP>:<PORT> 
Sec-Websocket-Version: 13
Sec-Websocket-Key: <KEY>
Connection: keep-alive, Upgrade
Upgrade: websocket

之后服务端会返回类似下面的数据

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: <ACCEPT_KEY>
Sec-WebSocket-Version: 13
Server: swoole-websocket-server

校检连接

这里可以对accept key进行校检,确定服务器确实是websocket服务器,校检算法为

sha1(KEY+‘258EAFA5-E914-47DA-95CA-C5AB0DC85B11’),将得到的一串字符串用16进制表示,之后再进行base64编码。

base64_encode(pack('H*', sha1(KEY.'258EAFA5-E914-47DA-95CA-C5AB0DC85B11')));

发送数据

websocket数据使用帧序列传输

来一张图

下面介绍的是这个数据包的含义。

FIN:长度1位,表示是否是最后一帧,为1则表示最后一帧,为0则表示还有后续帧

RSV(1-3):每一个1位,保留位。目前为0,如果服务端与客户端没有协商,那么非0则认为是一个错误的帧

opcode:表示帧格式,占4位,格式如下

 

0x00,表示继续帧
0x01,表示文本帧
0x02,表示二进制帧
0x03-0x07,保留的未定义非控制帧
0x08,连接关闭帧
0x09,表示ping
0xA,表示pong
0xB-0xF,用于保留的控制帧

 

MASK,1位,定义负载数据是否使用掩码,1为使用掩码,0为不使用掩码

Payload Length,7位,7+16位,7+64位,定义负载数据的长度,以字节为单位。这部分如果为0-125,则负载长度则就是这段定义的长度,如果为126,之后的 Extend payload Length 16位将作为负载长度,如果为127,那么之后的Extend payload Length 64位将作为负载长度。

负载数据长度为扩展数据长度+应用数据长度,扩展数据可以为0

Masking-key ,0 或者 32位,mask位设为0,则该字段缺失(不过协议要求,所有的帧都需要使用mask)

Payload data,负载数据=扩展数据+应用数据

Extension data,可以是客户端和服务端协商的长度,如果没有则为0

Application data,需要发送的真正的应用数据

赞赏

微信赞赏支付宝赞赏

发表评论

电子邮件地址不会被公开。 必填项已用*标注