/** * OPC WebSocket Client - Real-time updates */ let ws = null; let reconnectTimer = null; let listeners = new Set(); export function connect() { if (ws && ws.readyState === WebSocket.OPEN) { return; } const protocol = window.location.protocol === "https:" ? "wss:" : "ws:"; const wsUrl = `${protocol}//${window.location.host}/ws/opc`; ws = new WebSocket(wsUrl); ws.onopen = () => { console.log("OPC WebSocket connected"); if (reconnectTimer) { clearTimeout(reconnectTimer); reconnectTimer = null; } // Send ping every 30 seconds to keep connection alive const pingInterval = setInterval(() => { if (ws && ws.readyState === WebSocket.OPEN) { ws.send("ping"); } else { clearInterval(pingInterval); } }, 30000); }; ws.onmessage = (event) => { try { const message = JSON.parse(event.data); notifyListeners(message); } catch (e) { console.error("Failed to parse WebSocket message:", e); } }; ws.onerror = (error) => { console.error("WebSocket error:", error); }; ws.onclose = () => { console.log("OPC WebSocket disconnected"); ws = null; // Reconnect after 5 seconds reconnectTimer = setTimeout(() => { console.log("Reconnecting WebSocket..."); connect(); }, 5000); }; } export function disconnect() { if (ws) { ws.close(); ws = null; } if (reconnectTimer) { clearTimeout(reconnectTimer); reconnectTimer = null; } } export function subscribe(callback) { listeners.add(callback); return () => listeners.delete(callback); } function notifyListeners(message) { listeners.forEach((callback) => { try { callback(message); } catch (e) { console.error("Listener error:", e); } }); }