websocket协议详解

WebSocket是一种为了解决HTTP长连接问题而设计的新协议,它在HTTP基础上进行了升级,实现了服务端主动向客户端推送数据。握手过程使用HTTPUpgrade机制,之后通过数据帧进行通信,包括文本帧、二进制帧等,同时支持控制帧如关闭、ping/pong帧来管理连接状态。当TCP连接意外中断或接收到关闭帧时,WebSocket会话结束。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

websocket与http

WebSocket是HTML5出的东西(协议),也就是说HTTP协议没有变化,或者说没关系,但HTTP是不支持持久连接的(长连接,循环连接的不算) 首先HTTP有 1.1 和 1.0 之说,也就是所谓的 keep-alive ,把多个HTTP请求合并为一个,但是 Websocket 其实是一个新协议,跟HTTP协议基本没有关系,只是为了兼容现有浏览器的握手规范而已,也就是说它是HTTP协议上的一种补充可以通过这样一张图理解

 WebSocket 协议概述

WebSocket 协议主要为了解决基于 HTTP/1.x 的 Web 应用无法实现服务端向客户端主动推送的问题, 为了兼容现有的设施, WebSocket 协议使用与 HTTP 协议相同的端口, 并使用 HTTP Upgrade 机制来进行 WebSocket 握手, 当握手完成之后, 通信双方便可以按照 WebSocket 协议的方式进行交互

在 WebSocket 协议中, 帧 (frame) 是通信双方数据传输的基本单元, 与其它网络协议相同, frame 由 Header 和 Payload 两部分构成, frame 有多种类型, frame 的类型由其头部的 Opcode 字段 (将在下面讨论) 来指示, WebSocket 的 frame 可以分为两类, 一类是用于传输控制信息的 frame (如通知对方关闭 WebSocket 连接), 一类是用于传输应用数据的 frame, 使用 WebSocket 协议通信的双方都需要首先进行握手, 只有当握手成功之后才开始使用 frame 传输数据

 WebSocket 握手

当客户端想要使用 WebSocket 协议与服务端进行通信时, 首先需要确定服务端是否支持 WebSocket 协议, 因此 WebSocket 协议的第一步是进行握手, WebSocket 握手采用 HTTP Upgrade 机制, 客户端可以发送如下所示的结构发起握手 (请注意 WebSocket 握手只允许使用 HTTP GET 方法)

 WebSocket 消息与数据帧说明

Message 消息:1 条消息由一个或者多个帧组成,这些数据帧属于同一类型,代理服务器可能合并、拆分消息的数据帧。

Frame 数据帧:持续帧、文本帧、二进制帧

WebSocket 数据帧 (frame)

 WebSocket 以 frame 为单位传输数据, frame 是客户端和服务端数据传输的最小单元, 当一条消息过长时, 通信方可以将该消息拆分成多个 frame 发送, 接收方收到以后重新拼接、解码从而还原出完整的消息, 在 WebSocket 中, frame 有多种类型, frame 的类型由 frame 头部的 Opcode 字段指示, WebSocket frame 的结构如下所示:

 在这里插入图片描述

 FIN, 长度为 1 比特, 该标志位用于指示当前的 frame 是消息的最后一个分段, 因为 WebSocket 支持将长消息切分为若干个 frame 发送, 切分以后, 除了最后一个 frame, 前面的 frame 的 FIN 字段都为 0, 最后一个 frame 的 FIN 字段为 1, 当然, 若消息没有分段, 那么一个 frame 便包含了完成的消息, 此时其 FIN 字段值为 1

RSV 1 ~ 3, 这三个字段为保留字段, 只有在 WebSocket 扩展时用, 若不启用扩展, 则该三个字段应置为 1, 若接收方收到 RSV 1 ~ 3 不全为 0 的 frame, 并且双方没有协商使用 WebSocket 协议扩展, 则接收方应立即终止 WebSocket 连接

Opcode, 长度为 4 比特, 该字段将指示 frame 的类型, RFC 6455 定义的 Opcode 共有如下几种: 0x0, 代表当前是一个 continuation frame

0x1, 代表当前是一个 text frame

0x2, 代表当前是一个 binary frame

0x3 ~ 7, 目前保留, 以后将用作更多的非控制类 frame

0x8, 代表当前是一个 connection close, 用于关闭 WebSocket 连接

0x9, 代表当前是一个 ping frame (将在下面讨论)

0xA, 代表当前是一个 pong frame (将在下面讨论)

0xB ~ F, 目前保留, 以后将用作更多的控制类 frame

 Mask, 长度为 1 比特, 该字段是一个标志位, 用于指示 frame 的数据 (Payload) 是否使用掩码掩盖, RFC 6455 规定当且仅当由客户端向服务端发送的 frame, 需要使用掩码覆盖, 掩码覆盖主要为了解决代理缓存污染攻击 (更多细节见 RFC 6455 Section 10.3)

Payload Len, 以字节为单位指示 frame Payload 的长度, 该字段的长度可变, 可能为 7 比特, 也可能为 7 + 16 比特, 也可能为 7 + 64 比特. 具体来说, 当 Payload 的实际长度在 [0, 125] 时, 则 Payload Len 字段的长度为 7 比特, 它的值直接代表了 Payload 的实际长度; 当 Payload 的实际长度为 126 时, 则 Payload Len 后跟随的 16 位将被解释为 16-bit 的无符号整数, 该整数的值指示 Payload 的实际长度; 当 Payload 的实际长度为 127 时, 其后的 64 比特将被解释为 64-bit 的无符号整数, 该整数的值指示 Payload 的实际长度

Masking-key, 该字段为可选字段, 当 Mask 标志位为 1 时, 代表这是一个掩码覆盖的 frame, 此时 Masking-key 字段存在, 其长度为 32 位, RFC 6455 规定所有由客户端发往服务端的 frame 都必须使用掩码覆盖, 即对于所有由客户端发往服务端的 frame, 该字段都必须存在, 该字段的值是由客户端使用熵值足够大的随机数发生器生成, 关于掩码覆盖, 将下面讨论, 若 Mask 标识位 0, 则 frame 中将设置该字段 (注意是不设置该字段, 而不仅仅是不给该字段赋值)

Payload, 该字段的长度是任意的, 该字段即为 frame 的数据部分, 若通信双方协商使用了 WebSocket 扩展, 则该扩展数据 (Extension data) 也将存放在此处, 扩展数据 + 应用数据, 它们的长度和便为 Payload Len 字段指示的值

WebSocket 控制类 frame

控制类 frame 主要用来传输一些连接控制信息 (如 Close frame 用来关闭 WebSocket 连接), RFC 6455 总共定义了三种控制类 frame, 分别是 Close frame, Ping frame, Pong frame

Close frame, 顾名思义, 用来关闭 WebSocket 连接, 当需要关闭 WebSocket 连接时, 通信方向对方发送 Close frame, frame 可以包含 Payload, 如果包含, 则 Payload 的前两个字节以小端字节序表示的 16 位整数指示了相应的错误码, 在其后以 ASCII 编码只是一个错误原因, 这个错误原因不需要具有可读性, 一般用来做调试信息用, 当使用 WebSocket 通信的任何一方收到 Close frame 后, 应继续向对方返回一个 Close frame, 通常需要将错误码回显给对方, 当接收到 Close frame 并向对方发回 Close frame 后, 通信方便可以认为 WebSocket 连接已关闭, 此时应关闭底层的 TCP 连接

Ping frame 是作为一个探测性的 frame, 主要用来实现 WebSocket 层 Keep-Alive, 或者用来探测对方是否仍然是可回复的状态, Ping frame 可以包含 Payload

Pong frame 一方面作为 Ping frame 的响应, 接收方接收到 Ping frame 后应立即发回 Pong frame, 并且 Payload 的内容需要和 Ping frame 相同, 若接收方接收到了多个 Ping frame, 还没来得及回复 Pong frame, 则只需对最后一个 Ping frame 做出回复即可, 另一方面, Pong frame 可以由通信方主动发出, 作为一种心跳包

 

 关闭 WebSocket 会话

 控制帧中的关闭帧:在 TCP 连接之上的双向关闭。

发送关闭帧后,不能再发送任何数据。

接收关闭帧之后,不再接收任何到达的数据。

TCP 连接意外中断也会关闭 WebSocket。

websocket状态码

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值