WebSocket 是一种基于 TCP 的通信协议,旨在解决 传统 HTTP 协议在实时双向通信场景中的局限性。它允许客户端和服务端建立持久化连接,并支持全双工通信(客户端和服务端可以同时主动发送数据)。以下是 WebSocket 的详细介绍:
一、WebSocket 的核心特性
特性 | 说明 |
全双工通信 | 客户端和服务端可以同时发送和接收数据。 |
低延迟 | 数据帧直接传输,无需 HTTP 请求-响应机制。 |
持久连接 | 一次握手后保持长连接,避免重复建立连接的开销。 |
轻量级协议 | 数据包头较小(最小仅 2 字节),传输效率高。 |
支持二进制数据 | 可传输文本(UTF-8)或二进制数据(如图片、音频)。 |
二、WebSocket 与 HTTP 的对比
维度 | HTTP | WebSocket |
通信模式 | 单向(客户端主动请求,服务端响应) | 双向(客户端和服务端均可主动通信) |
连接生命周期 | 短连接(请求-响应后关闭) | 长连接(持久化,直到显式关闭) |
头部开销 | 每次请求需携带完整 HTTP 头部 | 初始握手后,后续通信头部极小 |
实时性 | 依赖轮询(Polling)或长轮询(Long Polling) | 原生支持实时推送 |
适用场景 | 静态资源获取、表单提交 | 实时聊天、在线游戏、股票行情推送 |
三、WebSocket 协议细节
1. 握手过程(Handshake)
WebSocket 连接通过 HTTP 协议升级(Upgrade)实现。以下是握手流程:
客户端请求:
GET /chat HTTP/1.1
Host: example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Sec-WebSocket-Version: 13
-
Upgrade: websocket
和Connection: Upgrade
表示请求升级协议。Sec-WebSocket-Key
是客户端生成的随机 Base64 字符串。Sec-WebSocket-Version
指定协议版本(通常为 13)。
服务端响应:
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
-
- 状态码
101
表示协议切换成功。 Sec-WebSocket-Accept
是服务端对客户端 Key 的计算结果,用于验证握手合法性。
- 状态码
2. 数据帧(Data Frames)
WebSocket 通信以帧(Frame)为单位传输数据。帧类型包括:
帧类型 | 说明 |
文本帧 | 携带 UTF-8 文本数据( |
二进制帧 | 携带二进制数据( |
连接控制帧 | Ping( |
- 帧结构:
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-------+-+-------------+-------------------------------+
|F|R|R|R| opcode|M| Payload len | Extended payload length |
|I|S|S|S| (4) |A| (7) | (16/64) |
|N|V|V|V| |S| | (if payload len == 126/127) |
| |1|2|3| |K| | |
+-+-+-+-+-------+-+-------------+ - - - - - - - - - - - - - - - +
| Extended payload length continued, if payload len == 127 |
+ - - - - - - - - - - - - - - - +-------------------------------+
| |Masking-key, if MASK set to 1 |
+-------------------------------+-------------------------------+
| Masking-key (continued) | Payload Data |
+-------------------------------- - - - - - - - - - - - - - - - +
: Payload Data continued ... :
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
| Payload Data continued ... |
+---------------------------------------------------------------+
3. 心跳机制(Ping/Pong)
- Ping 帧:服务端或客户端发送,用于检测连接是否存活。
- Pong 帧:接收方必须回复 Pong 帧(自动或手动),确认连接有效。
四、WebSocket 的应用场景
场景 | 说明 |
实时聊天 | 支持消息即时推送,如微信、Slack。 |
在线游戏 | 实时同步玩家动作和游戏状态。 |
股票行情 | 实时推送金融市场价格变动。 |
协同编辑 | 多人同时编辑文档(如 Google Docs)。 |
IoT 设备监控 | 实时接收传感器数据并下发控制指令。 |
五、WebSocket 的安全性
- 加密通信(WSS)
-
- 使用
wss://
协议(WebSocket over TLS),通过 SSL/TLS 加密数据。 - 配置方式与 HTTPS 类似,需服务端提供证书。
- 使用
- 跨域限制
-
- WebSocket 不受浏览器同源策略限制,但服务端可自定义验证逻辑(如检查
Origin
头)。
- WebSocket 不受浏览器同源策略限制,但服务端可自定义验证逻辑(如检查
- 输入验证
-
- 需对接收的数据进行合法性校验,防止注入攻击(如 XSS)。
六、WebSocket 代码示例(Java/Netty)
服务端处理器
public class WebSocketServerHandler extends SimpleChannelInboundHandler<TextWebSocketFrame> {@Overrideprotected void channelRead0(ChannelHandlerContext ctx, TextWebSocketFrame msg) {String request = msg.text();ctx.writeAndFlush(new TextWebSocketFrame("Server response: " + request));}@Overridepublic void userEventTriggered(ChannelHandlerContext ctx, Object evt) {if (evt instanceof WebSocketServerProtocolHandler.HandshakeComplete) {System.out.println("WebSocket 握手完成");}}
}
客户端(JavaScript)
const ws = new WebSocket('wss://example.com/chat');// 连接建立
ws.onopen = () => {ws.send('Hello Server!');
};// 接收消息
ws.onmessage = (event) => {console.log('收到消息:', event.data);
};// 连接关闭
ws.onclose = () => {console.log('连接关闭');
};
七、WebSocket 的优缺点
优点 | 缺点 |
低延迟,实时性强 | 长连接可能占用更多服务器资源 |
减少不必要的 HTTP 头部开销 | 需处理连接重连和状态恢复逻辑 |
支持双向通信 | 部分老旧浏览器或网络设备不支持 |
适合高频率、小数据量通信场景 | 需额外维护心跳机制防止连接超时 |
八、总结
WebSocket 是现代实时应用的核心技术之一,完美解决了 HTTP 在双向通信中的局限性。通过一次握手建立持久化连接,结合轻量级数据帧和心跳机制,使其成为在线聊天、实时数据推送等场景的首选方案。在实际开发中,需注意安全性和资源管理,合理设计重连与容错机制。