import { Subject } from "rxjs"; export type SocketState = "open" | "close" | "error"; class WebSocketClient { private ws: WebSocket | null = null; private url: string; private reconnectAttempts: number = -1; private maxReconnectAttempts: number = 5; private reconnectInterval: number = 3000; private dataSub = new Subject<{ func: string; data: Record | any[] }>(); get dataOb() { return this.dataSub.asObservable(); } private stateSub = new Subject(); get stateOb() { return this.stateSub.asObservable(); } constructor(url: string) { this.url = url; } // 连接 WebSocket connect(): void { try { // WebSocket.CONNECTING (0) WebSocket.OPEN (1) if (this.ws && this.ws.readyState <= 1) { // 已连接 console.log(`${this.url} 正在连接或已连接,无需重复连接`); } else { this.ws = new WebSocket(this.url); this.bindEvents(); } localStorage.setItem('wsReadyState', `${this.ws.readyState}`) } catch (error) { console.error("WebSocket 连接失败:", error); this.reconnect(); } } // 绑定事件 private bindEvents(): void { if (!this.ws) return; // 连接建立时的处理 this.ws.onopen = () => { console.log("WebSocket 连接已建立"); this.reconnectAttempts = -1; // 重置重连次数 this.stateSub.next("open"); }; // 接收消息的处理 this.ws.onmessage = (event: MessageEvent) => { try { const data = JSON.parse(event.data) as { func: string; data: Record | any[] }; // console.log("🚀 ~ WebSocketClient ~ bindEvents ~ data:", data); // if (data.type === "cmd") { // this.dataSub.next({ type: data.type, data: { ...data.data, success: data.data.status === "D0000" } }); // } else { this.dataSub.next(data); // } } catch (error) { console.error("消息解析错误:", error); } }; this.ws.onclose = () => { this.stateSub.next("close"); console.log("WebSocket 连接已关闭"); this.reconnect(); }; this.ws.onerror = error => { this.stateSub.next("error"); console.error("WebSocket 错误:", error); }; } // 重连机制 private reconnect(): void { if (this.reconnectAttempts === -1) { this.reconnectAttempts = 0; } if (this.reconnectAttempts >= this.maxReconnectAttempts) { console.log("达到最大重连次数,停止重连"); this.reconnectAttempts = -1; return; } setTimeout(() => { console.log(`尝试第 ${this.reconnectAttempts + 1} 次重连...`); this.reconnectAttempts++; this.connect(); }, this.reconnectInterval); } // 关闭连接 disconnect(): void { if (this.ws) { this.ws.close(); this.ws = null; } } } const urlSocketMap = new Map(); // 导出 WebSocket 客户端 export const createWebSocket = (url: string): WebSocketClient => { if (urlSocketMap.has(url)) { return urlSocketMap.get(url)!; } else { const client = new WebSocketClient(url); urlSocketMap.set(url, client); return client; } }; export const sharedWsUrl = `ws://${process.env.REACT_APP_WS_URL}`;