一、什么是WebSocket
WebSocket,即Web浏览器于Web服务器之间全双工通信标准,该技术主要是为了解决Ajax和Comet中的XMLHTTPRequest附带的缺陷所引起的问题。对于普通用户而言,只需要记住以下几点
• WebSocket可以在浏览器中使用
• 支持双向通信
• 弥补了Ajax带来的缺陷
相比与HTTP,ws有如下优点
• 支持双向通信,实时性更强
• 可以更好的支持二进制数据
• 在创建连接后,ws客户端与服务端进行数据交换时,协议控制的数据包头部较小,在不包含头部的情况下,服务端到客户端的包头只有2~10字节,客户端到服务端则需要加上额外的4字节的掩码。
• ws协议支持扩展,比如支持自定义的压缩算法等
二、实现
为了实现WS通信,在HTTP连接建立之后,需要完成一次握手步骤
创建连接和进行通信的数据包
关闭连接的数据包
1.1请求握手
1.2响应握手
Sec-WebSocket-Accept的字段是由握手请求中的Sec-WebSocket-Key字段值生成的,生成方式如下:将 Sec-WebSocket-Key 跟 258EAFA5-E914-47DA-95CA-C5AB0DC85B11 拼接,然后通过 SHA1 计算出摘要,并转成 base64 字符串。
•python实现如下:
1.3客户端请求包
1.4服务器响应包
1.5数据报文
客户端发送给服务器的数据,服务器需要进行解析,数据报文格式如下:
报文详细
1.FIN: 占 1bit
0:不是消息的最后一个分片
1:是消息的最后一个分片
2.RSV1, RSV2, RSV3:各占 1bit
一般情况下全为 0。当客户端、服务端协商采用 WebSocket 扩展时,这三个标志位可以非 0,且值的含义由扩展进行定义。如果出现非零的值,且并没有采用 WebSocket 扩展,连接出错。
3.Opcode: 4bit
%x0:表示一个延续帧。当 Opcode 为 0 时,表示本次数据传输采用了数据分片,当前收到的数据帧为其中一个数据分片;
%x1:表示这是一个文本帧(text frame);
%x2:表示这是一个二进制帧(binary frame);
%x3-7:保留的操作代码,用于后续定义的非控制帧;
%x8:表示连接断开;
%x9:表示这是一个心跳请求(ping);
%xA:表示这是一个心跳响应(pong);
%xB-F:保留的操作代码,用于后续定义的控制帧。
4.Mask: 1bit
表示是否要对数据载荷进行掩码异或操作。
0:否
1:是
5.Payload length: 7bit or (7 + 16)bit or (7 + 64)bit
表示数据载荷的长度。
0~126:数据的长度等于该值;
126:后续 2 个字节代表一个 16 位的无符号整数,该无符号整数的值为数据的长度;
127:后续 8 个字节代表一个 64 位的无符号整数(最高位为 0),该无符号整数的值为数据的长度。
6.Masking-key: 0 or 4bytes
当 Mask 为 1,则携带了 4 字节的 Masking-key;
当 Mask 为 0,则没有 Masking-key。
掩码算法:按位做循环异或运算,先对该位的索引取模来获得 Masking-key 中对应的值 x,然后对该位与 x 做异或,从而得到真实的 byte 数据。
注意:掩码的作用并不是为了防止数据泄密,而是为了防止早期版本的协议中存在的代理缓存污染攻击(proxy cache poisoning attacks)等问题。
7.Payload Data: 载荷数据
1.6服务器端代码实现
1.7客户端
将下面的代码直接保存为html文件,用浏览器打开即可
三、参考
python简单实现websocket
WebSocket 通信过程与实现
社群交流
领取专属 10元无门槛券
私享最新 技术干货