一、WebSocket 核心原理与优势
WebSocket 是一种基于 TCP 的全双工通信协议,通过单次握手建立持久连接
,实现客户端与服务端双向实时数据传输。相较于传统 HTTP 轮询,其优势包括:
- 低延迟:无需重复建立连接,减少握手开销.
- 高效通信:数据帧头部仅 2~10 字节,传输效率高.
- 主动推送:服务端可主动向客户端发送数据,无需等待请求.
二、前端实现 WebSocket 的步骤
1. 建立基础连接
javascript
// 客户端连接示例(使用加密协议wss)
const socket = new WebSocket("wss://your-domain.com/ws");
// 事件监听
socket.onopen = () => {
console.log("连接已建立");
socket.send(JSON.stringify({ type: "auth", token: "xxx" })); // 发送认证信息
};
socket.onmessage = (event) => {
const data = JSON.parse(event.data);
console.log("收到消息:", data);
};
socket.onerror = (error) => {
console.error("连接错误:", error);
};
socket.onclose = () => {
console.log("连接已关闭");
};
2. 服务端实现(Node.js 示例)
javascript
const WebSocket = require("ws");
const wss = new WebSocket.Server({ port: 8080 });
wss.on("connection", (ws) => {
ws.on("message", (message) => {
const data = JSON.parse(message);
// 广播消息给所有客户端
wss.clients.forEach((client) => {
if (client.readyState === WebSocket.OPEN) {
client.send(
JSON.stringify({ type: "broadcast", content: data.content })
);
}
});
});
});
三、高级功能实现
1. 心跳机制(保活)
javascript
// 客户端心跳发送
let heartbeatTimer;
socket.onopen = () => {
heartbeatTimer = setInterval(() => {
if (socket.readyState === WebSocket.OPEN) {
socket.send(JSON.stringify({ type: "heartbeat" }));
}
}, 30000); // 30秒一次
};
// 服务端检测心跳
ws.on("message", (message) => {
const data = JSON.parse(message);
if (data.type === "heartbeat") {
ws.lastPing = Date.now(); // 记录最新心跳时间
}
});
// 定时检查未响应连接
setInterval(() => {
wss.clients.forEach((ws) => {
if (Date.now() - ws.lastPing > 60000) {
// 超时60秒断开
ws.terminate();
}
});
}, 5000);
2. 自动重连机制
javascript
class ReconnectableWebSocket {
constructor(url) {
this.url = url;
this.reconnectInterval = 3000; // 3秒重试间隔
this.connect();
}
connect() {
this.ws = new WebSocket(this.url);
this.ws.onclose = () => {
setTimeout(() => this.connect(), this.reconnectInterval);
};
// 其他事件绑定...
}
}
3. 二进制数据传输
javascript
// 发送ArrayBuffer
const buffer = new ArrayBuffer(4);
const view = new DataView(buffer);
view.setUint32(0, 1234);
socket.send(buffer);
// 接收二进制数据
socket.binaryType = "arraybuffer";
socket.onmessage = (event) => {
if (event.data instanceof ArrayBuffer) {
const view = new DataView(event.data);
console.log("收到二进制数据:", view.getInt32(0));
}
};
四、安全性与跨域处理
- 使用 WSS 协议:通过 TLS 加密传输数据,防止中间人攻击。
- 验证 Origin 头:服务端需校验请求来源域名,防止 CSRF 攻击。
- 限制消息频率:防止客户端恶意发送高频消息。
五、推荐第三方库
- Socket.IO:支持自动降级(如轮询)与跨平台。
- ws(Node.js):轻量级服务端实现,适合高性能场景。
- SockJS:兼容老旧浏览器,提供 WebSocket 模拟。
六、适用场景与最佳实践
- 实时聊天:消息即时收发,支持群聊/私聊。
- 金融行情:毫秒级推送股票价格变动。
- 在线游戏:同步玩家动作与状态。
- 协同编辑:多人实时修改文档。
实践建议:
- 使用
readyState
属性管理连接状态(0-连接中,1-已连接,2-关闭中,3-已关闭)。 - 通过
bufferedAmount
监控未发送数据量,避免内存溢出。 - 结合
WebWorker
处理高频数据,减少主线程阻塞。
通过上述方案,前端项目可高效实现实时通信功能。具体代码示例可参考中的实战案例。