文章目录
-
-
- 一、先理清基础:HTTP为什么不支持全双工?
- 二、WebSocket升级的核心流程:从HTTP到全双工的"切换"
-
- [1. 第一步:HTTP握手(协议升级请求)](#1. 第一步:HTTP握手(协议升级请求))
- [2. 第二步:服务端确认升级](#2. 第二步:服务端确认升级)
- [3. 第三步:协议切换完成,TCP连接"复用"为WebSocket连接](#3. 第三步:协议切换完成,TCP连接“复用”为WebSocket连接)
- 三、WebSocket实现全双工的核心设计
-
- [1. 底层依赖:TCP的全双工特性(基础)](#1. 底层依赖:TCP的全双工特性(基础))
- [2. 帧化设计:打破"请求-响应"的边界](#2. 帧化设计:打破“请求-响应”的边界)
- [3. 无"请求-响应"绑定:主动推送能力](#3. 无“请求-响应”绑定:主动推送能力)
- [4. 持久连接:避免重复握手](#4. 持久连接:避免重复握手)
- [四、关键对比:HTTP vs WebSocket(全双工维度)](#四、关键对比:HTTP vs WebSocket(全双工维度))
- 五、总结
-
要理解WebSocket通过HTTP升级后实现 全双工通信 的核心逻辑,需先明确HTTP的通信特性,再拆解WebSocket升级的本质、协议设计的关键改动,以及底层传输层的支撑作用。
一、先理清基础:HTTP为什么不支持全双工?
HTTP(1.1/2)的核心限制决定了它无法原生全双工:
- 请求-响应模型:通信由客户端发起请求,服务端被动响应,响应完成后连接通常关闭(或复用但仍以"请求-响应"为单位);
- 单向性:同一连接上,同一时刻只能由一端(客户端→服务端)发送数据,服务端无法主动向客户端推送;
- 头部冗余:每次请求需携带大量HTTP头部,且无"帧化"设计,无法高效复用连接传输双向数据。
而全双工 的定义是:通信双方在同一连接上,可同时向对方发送数据(如同电话,双方可同时说话)。WebSocket的升级本质是"借HTTP的握手流程,切换到全新的全双工协议"。
二、WebSocket升级的核心流程:从HTTP到全双工的"切换"
WebSocket并非修改HTTP,而是以HTTP 1.1的Upgrade机制为"敲门砖",完成协议切换后,彻底脱离HTTP的请求-响应模型:
1. 第一步:HTTP握手(协议升级请求)
客户端向服务端发送HTTP请求,核心头信息如下:
http
GET /chat HTTP/1.1
Host: example.com
Upgrade: websocket // 核心:请求升级为WebSocket协议
Connection: Upgrade // 标识这是升级连接的请求
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ== // 随机密钥(防伪造) 随机生成的 base64 码
Sec-WebSocket-Version: 13 // 固定版本(主流)
2. 第二步:服务端确认升级
服务端验证密钥(用Sec-WebSocket-Key + 固定魔法字符串258EAFA5-E914-47DA-95CA-C5AB0DC85B11做SHA-1哈希并Base64编码),返回HTTP 101响应:
http
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo= // 验证后的密钥
3. 第三步:协议切换完成,TCP连接"复用"为WebSocket连接
之后,浏览器也用同样的公开算法将 base64码(Sec-WebSocket-Key) 转成另一段字符串,如果这段字符串跟服务器传回来的字符串一致,那验证通过。
此时,底层的TCP连接并未断开,但上层协议从HTTP完全切换为WebSocket协议------这是实现全双工的关键:TCP本身是全双工的,HTTP因上层规则限制了双向通信,而WebSocket移除了这些限制。
三、WebSocket实现全双工的核心设计
升级完成后,WebSocket协议通过以下设计,充分利用TCP的全双工特性:

1. 底层依赖:TCP的全双工特性(基础)
TCP连接本身就是全双工字节流:
- 每个TCP连接有两个独立的字节流通道(客户端→服务端、服务端→客户端);
- 两端可同时向对方写入数据,操作系统的TCP栈会处理数据的有序传输、重传、流量控制等。
HTTP的问题是上层协议规则(请求-响应)浪费了TCP的全双工能力,而WebSocket完全适配TCP的特性,不再限制数据传输的方向和时机。
2. 帧化设计:打破"请求-响应"的边界
WebSocket将数据拆分为帧(Frame),而非HTTP的"请求-响应"报文,帧是最小传输单元,核心特点:
- 双向帧传输:客户端和服务端可随时发送帧(文本帧、二进制帧、控制帧等),无需等待对方的"请求";
- 帧类型区分 :
- 数据帧(TEXT/BINARY):传输业务数据;
- 控制帧(PING/PONG/CLOSE):管理连接,无需响应;
- 无头部冗余:帧头仅2~10字节(包含操作码、长度、掩码等),远小于HTTP头部,且掩码仅客户端需添加(服务端无需),提升传输效率。
示例:客户端和服务端可同时发送帧,TCP栈会分别在两个方向传输:
客户端 → [TEXT帧:"你好"] → TCP通道1 → 服务端
服务端 → [TEXT帧:"世界"] → TCP通道2 → 客户端
3. 无"请求-响应"绑定:主动推送能力
WebSocket移除了HTTP的"请求必须先于响应"的规则:
- 服务端无需等待客户端请求,可主动向客户端发送帧(如实时消息、状态更新);
- 客户端也可连续发送帧,无需等待服务端确认;
- 两端的帧传输相互独立,仅受TCP流量控制(如滑动窗口)约束。
4. 持久连接:避免重复握手
WebSocket连接默认是持久的(除非主动关闭或超时),无需像HTTP 1.1那样通过Keep-Alive维持,且连接期间可双向传输任意数量的帧,避免了重复建立TCP连接的开销,进一步保障全双工通信的连续性。
四、关键对比:HTTP vs WebSocket(全双工维度)
| 特性 | HTTP 1.1/2 | WebSocket |
|---|---|---|
| 通信模型 | 请求-响应(客户端主导) | 无绑定的双向帧传输(双端平等) |
| 数据传输方向 | 单向(同一时刻仅客户端→服务端) | 双向同时(全双工) |
| 服务端主动推送 | 不支持(需轮询/长轮询模拟) | 原生支持 |
| 连接特性 | 短连接(或复用但仍按请求-响应划分) | 持久连接(全生命周期双向传输) |
| 传输单元 | 完整请求/响应报文(头部冗余大) | 轻量级帧(头部仅2~10字节) |
五、总结
WebSocket通过HTTP升级实现全双工的核心逻辑是:
- 借HTTP完成握手 :利用HTTP 1.1的
Upgrade机制,完成协议切换的身份验证,复用已建立的TCP连接; - 脱离HTTP规则:切换后抛弃HTTP的请求-响应模型,改用帧化传输;
- 适配TCP全双工:充分利用TCP的双向字节流特性,允许双端同时、主动发送帧,无方向和时机限制;
- 轻量级设计:帧化传输降低开销,持久连接保障连续性,最终实现真正的全双工通信。
简单来说:TCP是全双工的"硬件基础",HTTP因上层规则"禁用"了全双工,WebSocket则"解锁"了TCP的全双工能力。