名称: WebSocket常见陷阱 描述: “WebSocket服务器和客户端模式,包含心跳和重连机制。适用于实现实时功能、调试连接问题或审查WebSocket代码。触发关键词: WebSocket, wss, 心跳, 重连, 实时。”
WebSocket常见陷阱
WebSocket实现中的常见陷阱与正确模式。
使用时机
- 实现WebSocket服务器
- 构建带重连功能的WebSocket客户端
- 调试连接断开问题
- 添加心跳/ping-pong机制
- 审查WebSocket代码
工作流程
步骤 1: 验证服务器设置
检查WebSocket服务器是否共享HTTP端口。
步骤 2: 检查心跳机制
确保已实现ping/pong心跳。
步骤 3: 验证客户端重连
确认指数退避重连逻辑。
服务器模式
const wss = new WebSocketServer({ server: httpServer }); // 同一端口
wss.on('connection', (ws) => {
// 心跳
ws.isAlive = true;
ws.on('pong', () => { ws.isAlive = true; });
ws.on('message', (data) => {
try {
const msg = JSON.parse(data.toString());
// 验证消息类型
} catch {
ws.send(JSON.stringify({ error: '无效消息' }));
}
});
});
// 心跳间隔
setInterval(() => {
wss.clients.forEach((ws) => {
if (!ws.isAlive) return ws.terminate();
ws.isAlive = false;
ws.ping();
});
}, 30000);
客户端重连
// 客户端 - 带指数退避的重连逻辑
let attempt = 0;
function connect() {
const ws = new WebSocket(url);
ws.onopen = () => {
attempt = 0; // 成功连接后重置
};
ws.onclose = () => {
const delay = Math.min(1000 * Math.pow(2, attempt), 30000);
attempt++;
setTimeout(connect, delay);
};
ws.onerror = (error) => {
console.error('WebSocket错误:', error);
};
}
消息处理
// ✅ 始终验证和类型化消息
interface WsMessage {
type: 'subscribe' | 'unsubscribe' | 'ping';
channel?: string;
}
function handleMessage(ws: WebSocket, data: string) {
try {
const msg: WsMessage = JSON.parse(data);
switch (msg.type) {
case 'subscribe':
subscribeToChannel(ws, msg.channel);
break;
case 'ping':
ws.send(JSON.stringify({ type: 'pong' }));
break;
default:
ws.send(JSON.stringify({ error: '未知消息类型' }));
}
} catch {
ws.send(JSON.stringify({ error: '无效JSON' }));
}
}
快速检查清单
- [ ] WebSocket服务器使用与HTTP相同的端口
- [ ] 每30秒执行一次ping/pong心跳
- [ ] 客户端具有指数退避重连机制
- [ ] 消息在处理前经过验证
- [ ] 连接错误已记录