78 lines
4.6 KiB
Markdown
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
|