type MessageHandler = (data: Record) => void; class ChatSocket { private ws: WebSocket | null = null; private handlers: Map = new Map(); private reconnectTimer: ReturnType | null = null; connect() { const protocol = location.protocol === 'https:' ? 'wss:' : 'ws:'; const url = `${protocol}//${location.host}/ws`; this.ws = new WebSocket(url); this.ws.onopen = () => { this.emit('connected', {}); }; this.ws.onmessage = (event) => { try { const { type, data } = JSON.parse(event.data); this.emit(type, data); } catch {} }; this.ws.onclose = () => { this.reconnectTimer = setTimeout(() => this.connect(), 3000); }; } on(type: string, handler: MessageHandler) { if (!this.handlers.has(type)) this.handlers.set(type, []); this.handlers.get(type)!.push(handler); } off(type: string, handler: MessageHandler) { const list = this.handlers.get(type); if (list) this.handlers.set(type, list.filter((h) => h !== handler)); } send(type: string, data: Record = {}) { if (this.ws?.readyState === WebSocket.OPEN) { this.ws.send(JSON.stringify({ type, ...data })); } } stop() { this.send('stop'); } private emit(type: string, data: Record) { (this.handlers.get(type) || []).forEach((h) => h(data)); } disconnect() { if (this.reconnectTimer) clearTimeout(this.reconnectTimer); this.ws?.close(); } } export const chatSocket = new ChatSocket();