export class WebSocketClient { constructor(url = 'wss://localhost:8080') { this.url = url; this.reconnectAttempts = 0; this.maxReconnectAttempts = 5; this.reconnectDelay = 1000; this.maxReconnectDelay = 30000; this.socket = null; this.connected = false; this.reconnectTimeout = null; this.messageQueue = []; } connect() { if (this.socket && this.socket.readyState === WebSocket.OPEN) { return; } this.socket = new WebSocket(this.url); this.socket.onopen = () => { this.connected = true; this.reconnectAttempts = 0; this.messageQueue.forEach(msg => this.send(msg)); this.messageQueue = []; window.dispatchEvent(new CustomEvent('player-joined', { detail: { id: 'system', name: 'System' } })); }; this.socket.onmessage = (event) => { const data = JSON.parse(event.data); switch (data.type) { case 'player-joined': window.dispatchEvent(new CustomEvent('player-joined', { detail: data })); break; case 'player-left': window.dispatchEvent(new CustomEvent('player-left', { detail: data })); break; case 'chat-message': window.dispatchEvent(new CustomEvent('chat-message', { detail: data })); break; } }; this.socket.onclose = () => { this.connected = false; this.reconnect(); }; this.socket.onerror = (error) => { console.error('WebSocket error:', error); }; } reconnect() { if (this.reconnectAttempts >= this.maxReconnectAttempts) { console.warn('Max reconnection attempts reached.'); return; } this.reconnectTimeout = setTimeout(() => { this.reconnectAttempts++; this.connect(); }, Math.min(this.reconnectDelay * Math.pow(2, this.reconnectAttempts), this.maxReconnectDelay)); } send(message) { if (this.connected) { this.socket.send(JSON.stringify(message)); } else { this.messageQueue.push(message); } } disconnect() { if (this.socket) { this.socket.close(); } } } // Initialize and export a singleton instance export const wsClient = new WebSocketClient();