欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

websocket原理

程序员文章站 2022-05-21 09:29:53
...

HTTP的全称是超文本传输协议,英文写作HyperText Transfer Protocol。HTTP构建在TCP之上,属于应用层协议。

从协议的角度来说,现在的应用,如浏览器,其实是一个HTTP的代理,用户的行为将会通过它转化为HTTP请求报文发送给服务器端,服务器端在处理请求后,发送响应报文给代理,代理在解析报文后,将用户需要的内容呈现在界面上。

以浏览器打开一张图片地址为例:首先,浏览器构造HTTP报文发向图片服务器端;然后,服务器端判断报文中的要请求的地址,将磁盘中的图片文件以报文的形式发送给浏览器;浏览器接收完图片后,调用渲染引擎将其显示给用户。简而言之,HTTP服务只做两件事情:处理HTTP响应和发送HTTP请求。

WebSocket协议主要分为两个部分:握手和数据传输。下面我们来详细说一说这两个部分。

WebSocket握手

客户端建立连接时,通过HTTP发起请求报文,如下所示:

GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13

与普通的HTTP请求协议略有区别的部分在于如下这些协议头:

Upgrade: websocket
Connection: Upgrade

上述两个字段表示请求服务器端升级协议为WebSocket。其中 Sec-WebSocket-Key 用于安全校验:

Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==

在握手顺利完成后,当前连接将不再进行HTTP的交互,而是开始WebSocket的数据帧协议,实现客户端与服务器端的数据交换。
websocket原理
WebSocket数据帧的定义,每8位为一列,也即1个字节。其中每一位都有它的意义。
websocket原理

  1. fin :如果这个数据帧是最后一帧,这个 fin 位为1,其余情况为0。当一个数据没有被分为多帧时,它既是第一帧也是最后一帧。

  2. rsv1 、 rsv2 、 rsv3 :各为1位长,3个标识用于扩展,当有已协商的扩展时,这些值可能为1,其余情况为0。

  3. opcode :长为4位的操作码,可以用来表示0到15的值,用于解释当前数据帧。0表示附加数据帧,1表示文本数据帧,2表示二进制数据帧,8表示发送一个连接关闭的数据帧,9表示ping数据帧,10表示pong数据帧,其余值暂时没有定义。ping数据帧和pong数据帧用于心跳检测,当一端发送ping数据帧时,另一端必须发送pong数据帧作为响应,告知对方这一端仍然处于响应状态。

  4. masked :表示是否进行掩码处理,长度为1。客户端发送给服务器端时为1,服务器端发送给客户端时为0。

  5. payload length :一个7、7+16或7+64位长的数据位,标识数据的长度,如果值在0~125之间,那么该值就是数据的真实长度;如果值是126,则后面16位的值是数据的真实长度;如果值是127,则后面64位的值是数据的真实长度。

  6. masking key :当 masked 为1时存在,是一个32位长的数据位,用于解密数据。

  7. payload data :我们的目标数据,位数为8的倍数。

客户端发送消息时,需要构造一个或多个数据帧协议报文。由于 hello world! 较短,不存在分割为多个数据帧的情况,又由于 hello world! 会以文本的方式发送,它的 payload length 长度为96(12字节×8位/字节),二进制表示为1100000。所以报文应当如下:

fin(1) + res(000) + opcode(0001) + masked(1) + payload length(1100000) + masking key(32) + payload data(hello world!加密后的二进制)