1. WebSocket封装的核心价值与应用场景
WebSocket作为HTML5规范中的重要组成部分,已经成为现代Web应用中实时通信的标配技术。与传统的HTTP轮询相比,WebSocket提供了真正的全双工通信通道,特别适合需要实时数据更新的场景。我在多个电商大屏和金融交易系统中深度使用WebSocket后,发现原生API虽然简单易用,但在生产环境中直接使用会面临诸多挑战:
- 网络波动导致的连接中断问题(特别是在移动端场景)
- 长时间空闲连接被服务端主动断开
- 需要手动处理重连逻辑
- 事件监听器管理混乱
一个典型的股票行情页面可能需要在断开后自动恢复订阅信息,而在线协作编辑场景则需要保持文档状态的实时同步。这些业务需求催生了我们对WebSocket进行二次封装的需求。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 基础框架设计与实现
2.1 类结构设计
我们首先构建一个基础框架,这个框架需要保持与原生API相似的开发体验:
typescript复制export class WebSocketClient {
private url: string;
private socket: WebSocket | null = null;
constructor(url: string) {
this.url = url;
}
public connect(): void {
if (this.socket && this.socket.readyState === WebSocket.OPEN) {
return;
}
this.socket = new WebSocket(this.url);
this.socket.onopen = (event) => {
console.log('WebSocket连接已建立');
};
this.socket.onmessage = (event) => {
console.log('收到消息:', event.data);
};
this.socket.onclose = (event) => {
console.log('WebSocket连接已关闭');
};
this.socket.onerror = (event) => {
console.error('WebSocket错误:', event);
};
}
public send(message: string): void {
if (this.socket?.readyState === WebSocket.OPEN) {
this.socket.send(message);
}
}
public close(): void {
this.socket?.close();
}
}
这个基础版本已经实现了最核心的功能,但存在几个明显问题:
- 无法处理意外断开后的重连
- 没有心跳机制维持连接
- 事件监听不够灵活
2.2 事件系统增强
为了提供更灵活的事件处理,我们引入事件分发机制:
typescript复制class EventDispatcher {
private listeners: Record<string, Function[]> = {};
addEventListener(type: string, listener: Function): void {
if (!this.listeners[type]) {
this.listeners[type] = [];
}
this.listeners[type].push(listener);
}
removeEventListener(type: string, listener: Function): void {
const handlers = this.listeners[type];
if (handlers) {
this.listeners[type] = handlers.filter(fn => fn !== listener);
}
}
dispatchEvent(type: string, data?: any): void {
const handlers = this.listeners[type];
handlers?.forEach(handler => handler(data));
}
}
通过继承这个EventDispatcher,我们的WebSocketClient可以获得更强大的事件处理能力。
3. 断网重连机制实现
3.1 重连策略设计
在网络不稳定的环境下,自动重连是必须的功能。我们采用指数退避算法来实现智能重连:
typescript复制private reconnectAttempts = 0;
private maxReconnectAttempts = 5;
private baseReconnectInterval = 1000; // 1秒
private currentReconnectInterval = this.baseReconnectInterval;
private handleReconnect(): void {
if (this.reconnectAttempts >= this.maxReconnectAttempts) {
console.error('已达到最大重连次数');
return;
}
this.reconnectAttempts++;
this.currentReconnectInterval = Math.min(
this.baseReconnectInterval * Math.pow(2, this.reconnectAttempts - 1),
30000 // 最大间隔30秒
);
setTimeout(() => {
console.log(`第${this.reconnectAttempts}次重连尝试...`);
this.connect();
}, this.currentReconnectInterval);
}
这种策略可以避免在短时间内频繁重连造成服务器压力,同时又能保证最终能够恢复连接。
3.2 连接状态管理
我们需要完善连接状态管理,确保重连逻辑的正确执行:
typescript复制private isManualClose = false;
public close(): void {
this.isManualClose = true;
this.socket?.close();
}
private resetReconnectState(): void {
this.reconnectAttempts = 0;
this.currentReconnectInterval = this.baseReconnectInterval;
this.isManualClose = false;
}
在oncl
