/** * WebSocket连接管理类 */ export class WebSocketManager { private ws: WebSocket | null = null; private url: string; private reconnectAttempts = 0; private maxReconnectAttempts = 5; private reconnectInterval = 3000; private heartbeatInterval: NodeJS.Timeout | null = null; private heartbeatTimer = 30000; // 30秒心跳 // 事件回调 private onMessageCallback?: (data: any) => void; private onOpenCallback?: () => void; private onCloseCallback?: () => void; private onErrorCallback?: (error: Event) => void; constructor(url: string) { this.url = url; } /** * 连接WebSocket */ connect(): Promise { return new Promise((resolve, reject) => { try { this.ws = new WebSocket(this.url); this.ws.onopen = () => { console.log('WebSocket连接成功'); this.reconnectAttempts = 0; this.startHeartbeat(); this.onOpenCallback?.(); resolve(); }; this.ws.onmessage = (event) => { try { if(event.data !== '连接成功'){ const data = JSON.parse(event.data); console.log(data,'data>>>') this.onMessageCallback?.(data); } } catch (error) { console.error('解析WebSocket消息失败:', error); } }; this.ws.onclose = () => { console.log('WebSocket连接关闭'); this.stopHeartbeat(); this.onCloseCallback?.(); this.handleReconnect(); }; this.ws.onerror = (error) => { console.error('WebSocket连接错误:', error); this.onErrorCallback?.(error); reject(error); }; } catch (error) { reject(error); } }); } /** * 发送消息 */ send(message: any): void { if (this.ws && this.ws.readyState === WebSocket.OPEN) { this.ws.send(typeof message === 'string' ? message : JSON.stringify(message)); } else { console.warn('WebSocket未连接,无法发送消息'); } } /** * 关闭连接 */ close(): void { this.stopHeartbeat(); if (this.ws) { this.ws.close(); this.ws = null; } } /** * 重连处理 */ private handleReconnect(): void { if (this.reconnectAttempts < this.maxReconnectAttempts) { this.reconnectAttempts++; console.log(`尝试重连WebSocket (${this.reconnectAttempts}/${this.maxReconnectAttempts})`); setTimeout(() => { this.connect().catch(error => { console.error('重连失败:', error); // 继续尝试重连 this.handleReconnect(); }); }, this.reconnectInterval * this.reconnectAttempts); // 递增重连间隔 } else { console.error('WebSocket重连次数已达上限'); // 重置重连次数,以便后续手动重连 setTimeout(() => { this.reconnectAttempts = 0; }, 60000); // 1分钟后重置 } } /** * 开始心跳 */ private startHeartbeat(): void { this.heartbeatInterval = setInterval(() => { if (this.ws && this.ws.readyState === WebSocket.OPEN) { this.ws.send(JSON.stringify({ type: 'ping' })); } }, this.heartbeatTimer); } /** * 停止心跳 */ private stopHeartbeat(): void { if (this.heartbeatInterval) { clearInterval(this.heartbeatInterval); this.heartbeatInterval = null; } } /** * 设置消息回调 */ onMessage(callback: (data: any) => void): void { this.onMessageCallback = callback; } /** * 设置连接成功回调 */ onOpen(callback: () => void): void { this.onOpenCallback = callback; } /** * 设置连接关闭回调 */ onClose(callback: () => void): void { this.onCloseCallback = callback; } /** * 设置错误回调 */ onError(callback: (error: Event) => void): void { this.onErrorCallback = callback; } /** * 获取连接状态 */ getReadyState(): number { return this.ws?.readyState ?? WebSocket.CLOSED; } /** * 是否已连接 */ isConnected(): boolean { return this.ws?.readyState === WebSocket.OPEN; } } /** * 创建WebSocket连接 */ export function createWebSocket(url: string): WebSocketManager { return new WebSocketManager(url); }