WebSocket
在现代 Web 开发中,实时通信是许多应用的核心需求,例如在线聊天、实时协作、游戏对战等。WebSocket 是一种基于 TCP 的全双工通信协议,它允许客户端和服务器之间建立持久连接,并在双方之间高效地传输数据。
上一节分享了 「Server-Sent Events (SSE):轻量级实时通信技术」
WebSocket 的特点
1. 全双工通信
WebSocket 允许客户端和服务器双向发送消息,适用于需要频繁交互的场景,如即时聊天、在线游戏等。
// 客户端发送消息
socket.send('Hello Server!');
// 同时接收消息
socket.onmessage = (event) => {
console.log('收到服务端消息:', event.data);
};
- 双向实时: 客户端和服务端可以同时发送和接收数据
2. 持久连接
WebSocket 连接一旦建立,将保持打开状态,避免了 HTTP 轮询带来的性能损耗。
3. 低延迟
由于 WebSocket 仅在初始握手时使用 HTTP,之后的数据传输采用轻量级的帧格式,减少了额外的 HTTP 请求开销,提高了实时性。
4. 二进制和文本支持
WebSocket 支持发送文本数据和二进制数据,使其适用于多种应用场景,如音视频流、文件传输等。
5. 连接管理
相比 SSE(Server-Sent Events)只能由服务器推送数据,WebSocket 允许双向通信,因此需要手动管理连接的建立、丢失和恢复。
6. 二进制数据传输
// 发送ArrayBuffer
const buffer = new ArrayBuffer(128);
socket.send(buffer);
// 发送Blob数据
const blob = new Blob(['Hello']);
socket.send(blob);
原生支持: 无需编码转换,直接传输二进制数据
高效传输: 适合音视频流、文件传输等场景
类型灵活: 支持
ArrayBuffer
、Blob
、字符串等多种格式
WebSocket 协议详解
1. 握手过程
GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==
Sec-WebSocket-Version: 13
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk=
协议升级: 通过
HTTP Upgrade
机制切换到 WebSocket 协议安全验证: 基于
Sec-WebSocket-Key
的握手验证状态码: 成功返回
101 Switching Protocols
2. 数据帧结构
帧类型: 文本帧(0x1)、二进制帧(0x2)、控制帧等
分片传输: 支持将大消息拆分为多个帧传输
掩码处理: 客户端到服务端的数据需进行掩码处理
WebSocket 的实现
服务器端实现(Node.js + ws库)
1. 基础服务器
const WebSocket = require('ws');
const server = new WebSocket.Server({ port: 8080 });
server.on('connection', socket => {
console.log('Client connected');
// 监听客户端消息
socket.on('message', message => {
console.log('Received:', message);
socket.send(`Echo: ${message}`); // 发送回执消息
});
// 监听连接关闭
socket.on('close', () => {
console.log('Client disconnected');
});
});
console.log('WebSocket server running on ws://localhost:8080');
2. 广播功能实现
// 向所有客户端广播消息
wss.clients.forEach((client) => {
if (client.readyState === WebSocket.OPEN) {
client.send('广播消息');
}
});
3. 心跳机制
// 服务端心跳检测
setInterval(() => {
wss.clients.forEach((ws) => {
if (!ws.isAlive) return ws.terminate();
ws.isAlive = false;
ws.ping();
});
}, 30000);
ws.on('pong', () => {
ws.isAlive = true;
});
客户端实现(HTML + JavaScript)
1. 基础用法
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>WebSocket Demo</title>
<script>
document.addEventListener("DOMContentLoaded", function () {
const socket = new WebSocket('ws://localhost:8080');
// 连接成功
socket.onopen = function() {
console.log('WebSocket connection established');
socket.send('Hello Server!');
};
// 收到消息
socket.onmessage = function(event) {
console.log('Received:', event.data);
};
// 连接关闭
socket.onclose = function() {
console.log('WebSocket connection closed');
};
});
</script>
</head>
<body>
<h1>WebSocket Demo</h1>
<p>Check the console for messages.</p>
</body>
</html>
2. 断线重连
let reconnectAttempts = 0;
const maxReconnectAttempts = 5;
function connect() {
const socket = new WebSocket('wss://example.com/chat');
socket.onclose = () => {
if (reconnectAttempts < maxReconnectAttempts) {
setTimeout(connect, Math.pow(2, reconnectAttempts) * 1000);
reconnectAttempts++;
}
};
}
3. 二进制数据处理
// 接收ArrayBuffer
socket.binaryType = 'arraybuffer';
socket.onmessage = (event) => {
const buffer = event.data;
// 处理二进制数据
};
// 发送二进制数据
const buffer = new ArrayBuffer(32);
socket.send(buffer);
WebSocket 与 SSE 的比较
特性 | WebSocket | SSE |
---|---|---|
通信方式 | 双向通信 | 服务器到客户端单向推送 |
适用场景 | 聊天、游戏、实时协作 | 实时通知、日志更新、股票行情 |
连接管理 | 需手动管理重连 | 浏览器自动重连 |
数据格式 | 支持二进制和文本 | 仅支持文本 |
浏览器支持 | 现代浏览器均支持 | 现代浏览器均支持 |
WebSocket 的应用场景
- 即时通讯:WebSocket 非常适用于在线聊天、协作工具,如 Slack、微信 Web 版等【即时消息传递、在线状态更新、消息已读回执】。
- 在线游戏:多人在线游戏需要实时同步状态,WebSocket 由于其低延迟特性,是理想选择。
- 实时数据推送:股票、外汇等金融市场数据需要高频率推送,WebSocket 提供了高效的数据传输方式。
- 实时协作:如 Google Docs 这样的多人协作文档编辑工具,可使用 WebSocket 实现多个用户的实时同步【协同文档编辑、远程白板】。
- 物联网(IoT):WebSocket 可用于智能设备与服务器之间的通信,以实现远程监控和控制。
WebSocket优化实践
1. 性能优化
压缩扩展:启用
permessage-deflate
压缩连接池:合理管理 WebSocket 连接
负载均衡:使用支持 WebSocket 的负载均衡器
2. 安全防护
// 认证示例
wss.on('connection', (ws, req) => {
const token = req.headers['sec-websocket-protocol'];
if (!validateToken(token)) {
ws.close(1008, '未授权访问');
}
});
认证授权:通过子协议或自定义头进行身份验证
数据加密:强制使用wss(WebSocket Secure)
输入验证:严格校验客户端数据
3. 监控与调试
连接状态:实时监控连接数和消息吞吐量
错误日志:记录连接异常和错误信息
性能指标:跟踪消息延迟和资源使用情况
未来发展趋势
1. WebSocket over HTTP/3: 利用QUIC协议提升性能
2. WebTransport: 新一代实时通信协议
3. 边缘计算集成: 与CDN和边缘节点深度整合
4. 标准化扩展: 更丰富的子协议支持
总结
WebSocket 提供了一种高效、低延迟的双向通信方式,适用于各种需要实时交互的应用。相比于 SSE,它不仅支持服务器向客户端推送数据,还允许客户端主动发送数据,实现真正的实时双向通信。
如果你的应用涉及高频双向数据交换,如聊天、游戏或协作工具,WebSocket 是最佳选择!