diff --git a/diagnostic/server.js b/diagnostic/server.js index 3686d4a..43f261f 100644 --- a/diagnostic/server.js +++ b/diagnostic/server.js @@ -448,7 +448,13 @@ function connectRVS(forcePlain) { return; } - // TLS-Logik: wss zuerst, bei Fehler Fallback auf ws (wenn erlaubt) + // Alte Verbindung sauber schliessen + if (rvsWs) { + try { rvsWs.removeAllListeners(); rvsWs.close(); } catch (_) {} + rvsWs = null; + } + + // TLS-Logik: wss zuerst, bei Fehler Fallback auf ws const useTls = RVS_TLS === "true" && !forcePlain; const proto = useTls ? "wss" : "ws"; const url = `${proto}://${RVS_HOST}:${RVS_PORT}?token=${RVS_TOKEN}`; @@ -457,7 +463,18 @@ function connectRVS(forcePlain) { broadcastState(); log("info", "rvs", `Verbinde: ${proto}://${RVS_HOST}:${RVS_PORT}`); - const ws = new WebSocket(url); + let ws; + try { + ws = new WebSocket(url); + } catch (err) { + log("error", "rvs", `WebSocket erstellen fehlgeschlagen: ${err.message}`); + if (useTls && RVS_TLS_FALLBACK === "true") { + connectRVS(true); + } + return; + } + + let fallbackTriggered = false; ws.on("open", () => { log("info", "rvs", `Verbunden (${proto})`); @@ -465,6 +482,16 @@ function connectRVS(forcePlain) { state.rvs.lastError = null; rvsWs = ws; broadcastState(); + + // Keepalive: alle 25s ein Ping senden damit die Verbindung nicht stirbt + const keepalive = setInterval(() => { + if (ws.readyState === WebSocket.OPEN) { + try { ws.ping(); } catch (_) {} + } else { + clearInterval(keepalive); + } + }, 25000); + ws._keepalive = keepalive; }); ws.on("message", (raw) => { @@ -487,10 +514,13 @@ function connectRVS(forcePlain) { ws.on("close", () => { log("warn", "rvs", "Verbindung geschlossen"); + if (ws._keepalive) clearInterval(ws._keepalive); state.rvs.status = "disconnected"; - rvsWs = null; + if (rvsWs === ws) rvsWs = null; broadcastState(); - setTimeout(() => connectRVS(), 5000); + if (!fallbackTriggered) { + setTimeout(() => connectRVS(), 5000); + } }); ws.on("error", (err) => { @@ -498,11 +528,12 @@ function connectRVS(forcePlain) { state.rvs.lastError = err.message; broadcastState(); - // TLS Fallback: wenn wss fehlschlaegt und Fallback erlaubt → ws versuchen - if (useTls && RVS_TLS_FALLBACK === "true") { + // TLS Fallback + if (useTls && RVS_TLS_FALLBACK === "true" && !fallbackTriggered) { + fallbackTriggered = true; log("warn", "rvs", "TLS fehlgeschlagen — Fallback auf ws://"); - ws.removeAllListeners(); - try { ws.close(); } catch (_) {} + try { ws.removeAllListeners(); ws.close(); } catch (_) {} + if (rvsWs === ws) rvsWs = null; connectRVS(true); } });