当然可以,咱们从最基础讲起,我给你一个面向嵌入式或者刚入门的新人也能理解的 WebSocket 协议介绍。
1️⃣ WebSocket 是什么?
WebSocket 是一种在单个 TCP 连接上进行全双工通信的协议。
- 全双工:意味着服务器和客户端可以随时互相发送消息,不需要客户端每次都发请求。
- 基于 TCP:所以有可靠的传输保证,不会丢包(相比 UDP 的不可靠传输)。
简单类比:
- HTTP:就像你每次想说话都要敲门请求,然后等人回答。
- WebSocket:就像你们开了一条电话线,随时能讲随时能听。
2️⃣ WebSocket 的工作流程
握手(Handshake)
- 客户端通过 HTTP 请求发起握手:
GET /chat HTTP/1.1,并带上Upgrade: websocket和Connection: Upgrade。 - 服务器收到请求后,如果支持 WebSocket,会回应 101 Switching Protocols,表示协议切换成功。
- 客户端通过 HTTP 请求发起握手:
建立连接
- 握手成功后,TCP 连接不关闭,而是切换到 WebSocket 协议。
- 从此,客户端和服务器可以随时互相发送消息。
数据传输
- 数据以帧(Frame)为单位发送,可以是文本帧或二进制帧。
- 服务器和客户端可以同时发送数据,不必轮流(全双工)。
关闭连接
- 任意一方可以发送关闭帧(Close Frame)关闭连接。
3️⃣ WebSocket 数据帧结构简介
WebSocket 的数据帧比 HTTP 简单,主要字段包括:
| 字段 | 说明 |
|---|---|
| FIN | 是否是消息的最后一帧 |
| Opcode | 类型:文本、二进制、关闭、ping/pong 等 |
| Mask | 是否对数据进行掩码(客户端必须掩码) |
| Payload length | 数据长度 |
| Payload data | 真正发送的消息数据 |
举例:
- 文本消息
"hello"会被封装成一帧发送。 - 二进制数据(比如图像、音频)也可以通过帧发送。
4️⃣ WebSocket 的优点
- 实时性强:不用频繁建立 HTTP 请求。
- 节省带宽:只传数据,不传 HTTP 头。
- 全双工通信:客户端和服务器都能随时发消息。
- 适合长连接:比如聊天系统、实时监控、IoT 设备。
5️⃣ 简单应用案例
假设你在做嵌入式温湿度采集设备:
- 设备连接到 Wi-Fi,然后建立 WebSocket 到服务器。
- 服务器随时可以向设备发命令,比如“开始采集”、“停止采集”。
- 设备采集数据后,也可以随时推送到服务器。
- 由于是长连接,延迟很低,实时性好。
6️⃣ 小结
WebSocket = HTTP 协议升级 + 长连接 + 全双工通信
适合实时数据传输,尤其是 IoT、聊天应用、游戏、金融行情推送。
如果你需要,我可以帮你画一个WebSocket 握手 + 数据传输完整流程图,让你一眼就能看懂客户端和服务器的数据流。
你希望我画吗?
太好了,我给你画一个清晰的 WebSocket握手 + 数据传输流程图,分客户端和服务器两条线,标注关键帧和步骤。这里我用文字图的形式描述,你可以直接理解或者照着画成图:
客户端(Client) 服务器(Server) | | |———HTTP GET 请求,带 Upgrade: websocket———>| | GET /chat HTTP/1.1 | | Host: example.com | | Upgrade: websocket | | Connection: Upgrade | | Sec-WebSocket-Key: <随机值> | | Sec-WebSocket-Version: 13 | | | |<——101 Switching Protocols 响应——————————| | HTTP/1.1 101 Switching Protocols | | Upgrade: websocket | | Connection: Upgrade | | Sec-WebSocket-Accept: <计算值> | | | |———WebSocket 连接建立成功———————————————>| | | |<——————————服务器可以发送消息———————————| | | |———客户端可以发送消息———————————————>| | | |<———服务器发送 ping/pong 帧保持连接———>| | | |———客户端发送关闭帧 Close Frame ———————>| | | |<———服务器响应关闭帧 Close Frame ————>| | | |———连接关闭———————————————————————>|🔹流程解读:
HTTP 握手
- 客户端先用 HTTP 请求和服务器打招呼,并说“我想升级成 WebSocket”。
- 服务器确认后返回 101 Switching Protocols。
WebSocket 连接建立
- 握手成功后,TCP 长连接持续存在。
- 连接可用来双向发送消息。
数据传输
- 客户端和服务器随时可以发送文本或二进制帧。
- 也可以用 ping/pong 保活,防止长连接断开。
关闭连接
- 任意一方发送 Close Frame,另一方响应,连接优雅关闭。
💡小提示:
- 客户端发送的每一帧都必须Mask,服务器发送的不用。
- 数据可以是任意长度,分多帧发送也可以。
如果你愿意,我可以帮你画一个带消息帧详细标注(文本/二进制/close/ping)的更“可视化”的流程图,这样看起来就像真正的时序图,非常适合嵌入式开发理解数据流。
你想让我画这个吗?
没问题,我们重点来看WebSocket 的数据帧格式,这是理解它如何在客户端和服务器间传输数据的核心。咱们拆开讲,尽量详细但又容易理解。
1️⃣ WebSocket 帧(Frame)概念
WebSocket 传输的数据不是直接丢过去的,而是被封装成帧。每一帧包含头信息和有效载荷(Payload)。
- 文本帧(Text Frame):通常用于发送字符串数据,比如
"hello" - 二进制帧(Binary Frame):用于发送二进制数据,比如音频、图像、传感器数据
- 控制帧(Control Frame):用于 ping/pong 保活、关闭连接等
2️⃣ 帧结构总览
一个 WebSocket 帧的结构如下(字节级别):
| 字段 | 长度 | 说明 |
|---|---|---|
| FIN | 1 bit | 是否是消息的最后一帧。1 表示最后一帧,0 表示还有后续帧 |
| RSV1/RSV2/RSV3 | 1 bit each | 保留位,一般为 0,除非使用扩展协议 |
| Opcode | 4 bits | 操作码,表示帧类型 |
| Mask | 1 bit | 是否对 Payload 做掩码(客户端必须为 1,服务器为 0) |
| Payload length | 7/7+16/7+64 bits | 数据长度,分三种情况(0-125, 126-65535, >65535) |
| Masking key | 32 bits (4 bytes, 可选) | 如果 Mask = 1,则用于对 Payload 做掩码 |
| Payload data | 可变 | 真正的数据内容 |
3️⃣ Opcode(操作码)
操作码决定帧的类型:
| Opcode | 类型 | 说明 |
|---|---|---|
| 0x0 | continuation | 延续帧(多帧消息) |
| 0x1 | text | 文本帧(UTF-8 字符串) |
| 0x2 | binary | 二进制帧(图片、音频、传感器数据) |
| 0x8 | close | 关闭帧 |
| 0x9 | ping | ping 控制帧,服务器或客户端用来检查连接 |
| 0xA | pong | pong 控制帧,对 ping 的回应 |
4️⃣ Payload 长度编码
Payload length 7 位表示:
- 0–125:直接表示长度
- 126:后面 2 字节表示实际长度(16 位)
- 127:后面 8 字节表示实际长度(64 位)
例子:
- 文本
"hello"长度 5 → Payload length = 5 - 二进制数据 200 字节 → Payload length = 126 + 后面 2 字节表示 200
5️⃣ Masking
客户端发送给服务器的数据必须加掩码(Mask = 1),方法:
maskedPayload[i] = payload[i] XOR maskingKey[i % 4]- 服务器接收到后,用同样算法解码即可。
- 服务器发送给客户端时不需要掩码(Mask = 0)。
6️⃣ 控制帧示例
- Close Frame:客户端或服务器发起关闭连接
- Ping / Pong:保活连接、测延迟
例如客户端发送一个 Ping:
FIN=1, Opcode=0x9, Mask=1, Payload="ping"服务器收到后回应 Pong:
FIN=1, Opcode=0xA, Mask=0, Payload="ping"7️⃣ 文本帧示例(“Hi”)
假设客户端发送"Hi"(UTF-8 2 字节):
| 字节 | 说明 |
|---|---|
| 0x81 | FIN=1, Opcode=1(文本) |
| 0x82 | Mask=1, Payload length=2 |
| 0x12 0x34 0x56 0x78 | Masking key(随机) |
| 0x4A 0x2B | Payload (HiXOR Masking key) |
服务器收到后解码,得到"Hi"。
💡总结要点
- WebSocket 帧由头 + 可选掩码 + 数据构成
- Opcode 决定帧类型:文本、二进制、控制
- FIN 决定消息是否结束
- 客户端必须 Mask,服务器可不 Mask
- Payload 可分多帧发送,支持大数据传输
如果你愿意,我可以帮你画一个WebSocket 帧结构图,直观显示 FIN、Opcode、Mask、Payload 长度、Masking key、Payload 的字节布局,看起来就像内存图,很适合嵌入式开发理解数据封包。
你希望我画吗?