WebSocket协议
HTTP/TCPTechnology
WebSocket协议
以有一定基础(如了解 TCP、HTTP、Socket 编程等)的开发者的视角来解释 WebSocket(ws)协议。
✅ WebSocket 是什么?
WebSocket(简称 ws)是一种在单个 TCP 连接上进行全双工、长连接通信的协议。它由 IETF 标准化为 RFC 6455,用于浏览器和服务器之间的低延迟通信。
✅ WebSocket 是基于 TCP 实现的吗?
是的,WebSocket 协议是完全基于 TCP 之上实现的。
它的通信栈大致如下:
应用层: WebSocket
传输层: TCP
网络层: IP
链路层: Ethernet / Wi-Fi ...
也就是说:
- WebSocket = 应用层协议
- TCP = 传输层协议
🔄 WebSocket 和 HTTP 有什么关系?
WebSocket 并不是 HTTP 协议的子集,但它的握手阶段是基于 HTTP 的。流程如下:
握手过程(建立连接):
客户端发送一个 HTTP 请求(带 Upgrade 头)给服务器:
httpGET /chat HTTP/1.1 Host: example.com Upgrade: websocket Connection: Upgrade Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ== Sec-WebSocket-Version: 13
服务器响应:
httpHTTP/1.1 101 Switching Protocols Upgrade: websocket Connection: Upgrade Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
之后,这条 TCP 连接就“升级”为 WebSocket 连接,开始进行非 HTTP 格式的、全双工的数据帧通信。
📦 WebSocket 的数据传输特点
- 长连接:只需握手一次,之后持续复用 TCP 连接。
- 全双工:客户端和服务器可以同时、独立地发送数据。
- 轻量数据帧格式:相比 HTTP 请求头、响应头,WebSocket 的帧结构更紧凑高效。
- 低延迟:适合聊天、游戏、实时数据推送、协同编辑等场景。
📌 ws:// 与 wss:// 的区别?
ws://
—— 基于普通 TCP(明文传输)wss://
—— 基于 TLS 加密的 WebSocket,相当于 WebSocket over HTTPS(SSL)
比如:
ws://example.com:8080/
→ 明文 TCPwss://example.com/
→ TLS 加密(更安全)
🔧 与传统 HTTP 请求的对比
特性 | HTTP | WebSocket |
---|---|---|
协议类型 | 请求-响应 | 全双工 |
连接生命周期 | 每次请求重建连接 | 长连接(握手后复用) |
服务器主动推送 | 不支持(除 SSE) | 支持(服务端可主动推) |
数据传输开销 | 高(Header 较大) | 小(数据帧) |
实现难度 | 简单 | 稍复杂(需握手和帧处理) |
🧠 总结一句话:
WebSocket 是建立在 TCP 基础上的全双工通信协议,使用一次 HTTP 握手“升级”连接,之后进行高效、持久的二进制数据帧传输,适用于实时通信场景。
WebSocket 协议的内部机制与实现细节
深入讲解一下 WebSocket 协议的内部机制与实现细节,这些对作为有基础的开发者来说非常有价值。
🧱 一、WebSocket 数据帧格式
WebSocket 握手成功后,通信双方就用**数据帧(Frame)**的形式来发送消息。
📦 基础帧结构(RFC 6455)
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|F|R|R|R| opcode|M| Payload len |
|I|S|S|S| (4b) |A| (7b) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Extended payload length |
+------------------------------+
| Masking key (32 bits) |
+------------------------------+
| Payload Data |
+------------------------------+
各字段说明:
- FIN(1 bit):是否是该消息的最后一个帧(1 表示结束)
- Opcode(4 bit):
0x1
:文本帧(UTF-8 编码)0x2
:二进制帧0x8
:连接关闭帧0x9
:Ping(心跳)0xA
:Pong(回应心跳)
- Mask(1 bit):是否使用掩码(客户端必须为 1,服务器通常为 0)
- Payload len(7+ bits):
0-125
:长度126
:后两个字节表示真实长度127
:后八个字节表示真实长度
- Masking key(4 字节):用于将客户端数据掩码处理
- Payload Data:实际传输的数据内容(被掩码)
📌 所以 WebSocket 的数据传输并非“明文文本”,即便是文本帧,也会被掩码处理。
🔄 二、Ping-Pong 心跳机制
WebSocket 是长连接协议,为防止连接断掉,客户端或服务端可定期发送 Ping
帧,另一方必须响应 Pong
。
- Ping:客户端或服务器发送
- Pong:被动响应(或也可主动发送)
用途:
- 保持连接活性
- 探测断开(如果
Pong
超时未收到,可视为断开)
🔁 三、断线重连
WebSocket 不会自动重连,常见的客户端重连策略:
jslet ws; function connect() { ws = new WebSocket("ws://example.com"); ws.onopen = () => console.log("Connected"); ws.onclose = () => { console.log("Disconnected, retrying..."); setTimeout(connect, 3000); // 3 秒后重连 }; ws.onerror = (err) => console.error("Error", err); } connect();
🔗 四、与 Socket.IO 的区别
对比项 | WebSocket 原生 | Socket.IO (封装库) |
---|---|---|
协议 | WebSocket | 自定义协议(基于 ws + fallback) |
兼容性 | 仅现代浏览器 | 自动 fallback 到 HTTP 长轮询 |
连接管理 | 自己处理 | 内置心跳、重连、ACK 等 |
事件系统 | 不支持 | 内置 emit / on 事件机制 |
功能性 | 纯通信 | 支持房间、命名空间等 |
服务端依赖 | 任意语言实现 ws | 需配套 socket.io server |
🎯 如果你需要自己控制一切细节或用非 JS 后端:建议原生 WebSocket 🧰 如果你用 Node.js 并追求开发效率:可以用 Socket.IO
🔐 五、安全注意事项(特别是在生产环境)
- 使用
wss://
加密传输- 避免中间人攻击(MITM)
- 鉴权机制(WebSocket 本身没有)
- 使用 cookie / URL token / 握手 header 传递身份信息
- 服务端拦截
Upgrade
请求验证用户
- 连接数限制与资源控制
- 每个连接会占用一个线程/协程 +内存
- 消息大小和频率限制
- 防止 WebSocket 被滥用为 DoS 攻击工具
🚀 六、使用场景举例
- ✅ 实时聊天 / 通知(如微信网页版)
- ✅ 实时协作(如 Google Docs)
- ✅ 实时行情 / 股票推送
- ✅ 游戏对战 / 数据同步
- ✅ 物联网(IoT)消息通道
✅ 小结
- WebSocket 是基于 TCP 的双向通信协议
- 初始连接用 HTTP 完成握手,随后完全脱离 HTTP
- 高效、低延迟、适合实时应用
- 数据是帧结构传输,支持心跳机制
- 可使用 Socket.IO 等封装库简化开发