WebSocket 握手的原理是什么?其实很简单,因为只有一次握手:
-
首先客户端会发送一个握手包,其中:
- 方法必须是 GET 方法
- HTTP 版本不能低于1.1
- 必须包含 Upgrade 头部,值必须为 websocket
- 必须包含 Sec-WebSocket-Key 头部,值是一个 Base64 编码的 16 字节随机字符串
- 必须包含 Sec-WebSocket-Version 头部,值必须为 13
其他可选首部可以参考 rfc6455 文档,示例请求头如下:
GET ws://localhost:7002/ HTTP/1.1 Host: localhost:7002 Connection: Upgrade Upgrade: websocket Sec-WebSocket-Version: 13 Accept-Encoding: gzip, deflate, br Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,ja;q=0.7 Sec-WebSocket-Key: yEwVMqDyEwAgAKNzFEzgPw== Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits 复制代码
-
服务端验证客户端的握手包符合规范之后,也会发送一个握手包给客户端,格式如下:
- 必须包含 Connection 头部,值必须为 Upgrade
- 必须包含一个 Upgrade 头部,值必须为 websocket
- 必须包含一个 Sec-Websocket-Accept 头部
其中,Sec-Websocket-Accept 头部的值是根据如下规则计算的:
- 首先将一个固定的字符串 258EAFA5-E914-47DA-95CA-C5AB0DC85B11 拼接到 Sec-WebSocket-Key 对应值的后面。
- 对拼接后的字符串进行一次 SHA-1 计算
- 将计算结果进行 Base64 编码
演示代码如下:
crypto.createHash('sha1').update(webSocketKey + wsGUID).digest('base64') 复制代码
示例响应头如下:
HTTP/1.1 101 Switching Protocols Upgrade: websocket Connection: Upgrade Sec-WebSocket-Accept: rVYiZQwHfb4oDr4MkkMYo6lbeaY= 复制代码
-
客户端收到服务端的握手包之后,验证报文格式是否符合规范。(即用 2 中同样的方式计算 Sec-WebSocket-Accept 并与服务端握手包里的值进行比对)
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END