Files
appRobotDriver/doc/ToDo_10_VerbindungsVerlust.md
2026-06-09 12:05:18 +02:00

78 lines
4.6 KiB
Markdown

# 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