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 头)给服务器:

http
GET /chat HTTP/1.1
Host: example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Sec-WebSocket-Version: 13

服务器响应:

http
HTTP/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/ → 明文 TCP
  • wss://example.com/ → TLS 加密(更安全)

🔧 与传统 HTTP 请求的对比

特性HTTPWebSocket
协议类型请求-响应全双工
连接生命周期每次请求重建连接长连接(握手后复用)
服务器主动推送不支持(除 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 不会自动重连,常见的客户端重连策略:

js
let 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


🔐 五、安全注意事项(特别是在生产环境)

  1. 使用 wss:// 加密传输
    • 避免中间人攻击(MITM)
  2. 鉴权机制(WebSocket 本身没有)
    • 使用 cookie / URL token / 握手 header 传递身份信息
    • 服务端拦截 Upgrade 请求验证用户
  3. 连接数限制与资源控制
    • 每个连接会占用一个线程/协程 +内存
  4. 消息大小和频率限制
    • 防止 WebSocket 被滥用为 DoS 攻击工具

🚀 六、使用场景举例

  • 实时聊天 / 通知(如微信网页版)
  • 实时协作(如 Google Docs)
  • 实时行情 / 股票推送
  • 游戏对战 / 数据同步
  • 物联网(IoT)消息通道

✅ 小结

  • WebSocket 是基于 TCP 的双向通信协议
  • 初始连接用 HTTP 完成握手,随后完全脱离 HTTP
  • 高效、低延迟、适合实时应用
  • 数据是帧结构传输,支持心跳机制
  • 可使用 Socket.IO 等封装库简化开发