# ToDo 10 — Verbindungsverlust erkennen und anzeigen ## Problem Wenn der Telnet-Server (oder später die WS-Verbindung) wegbricht — kein Strom, Netzwerkausfall, Firewall-Drop — wird das weder im Container-Log noch auf der Info-Webseite angezeigt. Die Status-Seite zeigt dauerhaft „alles grün", obwohl kein Sender mehr erreichbar ist. Die Ursache: TCP-Sockets können „still sterben". Der Socket ist auf Node.js-Seite noch offen, das `close`-Event feuert nicht (z. B. bei Firewall-Drop oder Netzwerk-Timeout), und der aktuelle Health-Check in `InfoServer.js` prüft nur `tSocket != null` — das bleibt `true`. ## Abgrenzung zu anderen ToDos | ToDo | Thema | Überschneidung | |---|---|---| | **ToDo_2** | Reconnect-Strategie, Sender-Interface, `state`-Property | Fundament — ToDo_10 baut darauf auf und ergänzt den Watchdog | | **ToDo_5** | Health-Checks in `/api/status` | Dort angelegt; ToDo_10 füllt die fehlende Tiefe | | **ToDo_9** | Timeout bei ausbleibenden GRBL-`ok`-Antworten | Ergänzend: ToDo_9 = Protokoll-Ebene, ToDo_10 = Verbindungs-Ebene | **Was hier neu ist:** aktiver Watchdog-Heartbeat (auch bei scheinbar offenem Socket), vollständige State-Machine mit sichtbarem Reconnect-Zyklus, und UI-Visualisierung in `public/app.js` — das deckt kein anderes ToDo ab. **Voraussetzung:** ToDo_2 muss abgeschlossen sein (`state`-Property und Sender-Interface existieren). --- ## Hinweis: Das Problem betrifft Telnet und WebSocket gleichermaßen Das „stille Sterben" ist kein Telnet-spezifisches Problem — es ist ein TCP-Problem. WebSocket läuft ebenfalls über TCP und hat dieselbe Schwachstelle, wenn kein aktiver Keepalive verwendet wird. Der Unterschied liegt im verfügbaren Gegenmittel: | Transport | Klasse | Mechanismus | |---|---|---| | **Telnet** | `TelnetSenderGRBL.js` | Applikations-Watchdog: Timer + Schreib-Probe (kein Protokoll-Support) | | **WebSocket** | `WSSenderGrbl.js` | WebSocket Ping/Pong (RFC 6455, Protokollebene) — sauberer und standardisiert; aktuell **nicht** aktiviert | `WSSenderGrbl.js` verwaltet das `ws`-WebSocket-Objekt direkt und hat bereits eine State-Machine (`state`, `reconnectAttempt`, `reconnectTimer`). Die Reconnect-Logik bei `close`- und `error`-Events ist implementiert. Was noch fehlt, ist der aktive Ping/Pong-Heartbeat für den Fall des stillen TCP-Todes. `FluidNCClient.js` ist ein älterer, paralleler Ansatz und wird von `WSSenderGrbl.js` **nicht** verwendet. --- ## Paket 1: Watchdog im Sender `WSSenderGrbl.js` hat bereits State-Machine und Reconnect-Logik. Offen bleibt: - [ ] Aktiven Heartbeat einführen — nicht nur auf das `close`-Event warten - **WebSocket (`WSSenderGrbl.js`):** WebSocket Ping/Pong aktivieren — `ws.ping()` alle 30 s, bei ausbleibendem Pong Verbindung als tot markieren und Reconnect auslösen - **Telnet (`TelnetSenderGRBL.js`):** Timer + applikationsseitige Schreib-Probe, da kein Protokoll-Support - erkennt „stille" Socket-Tode, bei denen kein `close`-Event feuert - [ ] State-Machine im Sender konsolidieren - Zustände: `connected` | `connecting` | `reconnecting` | `disconnected` - `reconnectAttempt` (Zähler) und `reconnectDelay` (aktuelle Wartezeit) als Properties - bei Verbindungsverlust: `state` → `disconnected`, Reconnect-Zyklus starten (1 min / 2 min Intervall) - [ ] Fehlerzustand und Reconnect-Fortschritt loggbar machen - im Container-Log erkennbar: welcher Sender, welcher Zustand, nächster Versuch wann ## Paket 2: Status-API vertiefen - [ ] `InfoServer.js` `/api/status` liefert echten Sender-Zustand aus der State-Machine - nicht mehr nur `tSocket != null`, sondern `sender.getStatus()` mit `state`, `reconnectAttempt`, `lastSeen` - bei `disconnected` oder `reconnecting`: `health`-Summary auf `degraded` setzen - [ ] `lastSeen`-Timestamp pro Sender führen - wann wurde zuletzt erfolgreich gesendet oder eine Antwort empfangen? - hilft Diagnose: Sender tot seit X Sekunden ## Paket 3: UI-Visualisierung - [ ] `public/app.js` wertet den Sender-Status aus `/api/status` aus - Farb-Indikator pro Sender: grün / gelb (reconnecting) / rot (disconnected) - bei `reconnecting`: Anzeige von Versuchs-Nummer und nächstem Retry-Zeitpunkt - [ ] Statuswechsel sofort sichtbar machen - `/api/status` wird periodisch (z. B. alle 10 s) abgefragt oder per WebSocket-Push aktualisiert ## Betroffene Dateien - `robot/TelnetSenderGRBL.js` (oder künftiger Sender) — Watchdog-Logik, State-Machine - `server/InfoServer.js` — tieferer Status-Abruf via `getStatus()` - `public/app.js` — Visualisierung des Verbindungszustands - `startRobot.js` — keine Änderung erwartet, Sender-Interface bleibt gleich