Repository navigation
Reconnect/Resume instabil (App Service + iOS Safari) inkl. ~4-Minuten Idle Disconnect #169
Copy link
Copy link
Closed
Labels
backendThis issue is specific to the backendThis issue is specific to the backend
Milestone
Description
Kurzbeschreibung
Der Web-Client verliert unter bestimmten Bedingungen die Verbindung (Socket und/oder Telnet-Zuordnung) und kann diese nicht zuverlässig wiederherstellen. Besonders auf iOS/Safari ist ein "Neuladen" der Seite oft kein echter Reset, sodass Nutzer in einem kaputten Zustand hängen bleiben und viele Versuche benötigen, bis wieder eine funktionierende Verbindung entsteht.
Beobachtetes Verhalten
A) Disconnect nach Inaktivität (~4 Minuten)
- Auch bei offenem Tab (ohne Interaktion) wird die Verbindung nach ca. 4 Minuten getrennt
- Der Client zeigt keinen eindeutigen Verbindungsstatus an (wird in Issue 1 separat behandelt)
- Nach einem Reload bekommt man (auf Desktop) wie erwartet eine neue Verbindung und sieht den Startscreen
B) Resume funktioniert nur innerhalb kurzer Zeit
- Test: Tab geschlossen, nach ~2 Minuten Seite wieder geöffnet
- Verbindung wurde wieder aufgenommen, Eingaben funktionierten
- Test: Tab geschlossen oder inaktiv, nach ~4–5 Minuten
- Verbindung war unterbrochen, Gast ausgeloggt
- Neu laden -> neue Verbindung (Startscreen)
C) Plattformunterschiede beim „Neu laden“
- Windows (Chrome): Reload funktioniert zuverlässig und führt zu einer neuen Verbindung
- iOS (Safari):
- iPad: Nutzer muss sehr oft neu laden, bis die Seite wirklich neu lädt und eine neue Verbindung aufbaut
- iPhone: besser, aber weiterhin unzuverlässig
- Der Nutzerbericht deutet darauf hin, dass „Reload“ unter iOS/Safari häufig nicht als vollständiger Neustart der App wirkt
D) Unterschied zu anderen Clients
- Mit einem anderen (nicht-Web-)Client tritt der ~4-Minuten Inaktivitätsdisconnect nicht auf
- Der Web-Client verhält sich hier offensichtlich anders (oder ist anders betroffen durch Infrastruktur/Browser)
Erwartetes Verhalten
- Verbindung bleibt stabil, oder der Disconnect wird sauber erkannt und führt in einen definierten Zustand
- Reconnect/Resume sollte deterministisch funktionieren oder sauber auf „neue Verbindung“ fallen
- Ein „Neu laden“ der Seite sollte zuverlässig zu einem klaren, neuen Verbindungsaufbau führen (insb. auf iOS/Safari)
Relevante Fakten / Hinweise aus Codeanalyse
- Client und Server erzwingen
transports: ['websocket'](kein Long-Polling-Fallback) - Für Socket.IO sind keine expliziten
pingInterval/pingTimeoutgesetzt (Defaults) - Der einzige explizite Backend-Timer ist
SOCKET_TIMEOUT(Default 15 Minuten) für:- connectionStateRecovery.maxDisconnectionDuration
- späteres Close der Telnet-Verbindung nach Socket-Disconnect
- Der beobachtete ~4-Minuten Disconnect wird dadurch vermutlich nicht direkt im Code ausgelöst, sondern eher durch:
- Infrastruktur-Idle-Timeouts (Azure App Service / Proxy / LB) oder
- Browser-/Lifecycle-Verhalten (iOS Safari) oder
- Telnet/MUD-seitige Idle-Mechanismen (Timing-Mark separat in Timing-Mark (TM) Handling kann Telnet-Disconnects auslösen #168)
Vermutete Einflussfaktoren (ohne Festlegung)
- Azure App Service / Infrastruktur kann idle WebSocket-Verbindungen nach wenigen Minuten trennen
- iOS Safari kann Tabs im Hintergrund einfrieren und Netzwerkverbindungen still beenden
- „Reload“ in Safari führt nicht immer zu einem vollständigen Reset (z. B. Cache/Lifecycle/bfcache-Effekte)
- WS-only Transport macht das System empfindlicher, weil es keinen Fallback gibt
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
backendThis issue is specific to the backendThis issue is specific to the backend
Activity
mystiker commentedon Feb 8, 2026
Ich habe das lokal getestet: dort kein Disconnect nach ~4 Minuten. Auf Azure sehe ich dagegen reproduzierbar einen Idle‑Disconnect. Auszug aus den Logs:
Letzte Aktivität um 22:44:25
Danach Azure Trace-Meldungen:
In den letzten 1/2/3/4 Minuten wurde keine neue Ablaufverfolgung ausgeführt.
Direkt danach:
uncaughtException: read ECONNRESET
Stack: TCP.onStreamRead → async_hooks.callbackTrampoline
Unmittelbar gefolgt von:
[[Socket-Manager] Client telnet connection closed. Emitting 'mudDisconnected']
=> Das deutet stark auf Azure/Infra Idle Timeout / Connection Reset als Ursache hin (nicht App‑intern, nicht der SOCKET_TIMEOUT im Code, der 15min default wäre).
Logauszug (gekürzt):
2026-02-08T22:48:53.895Z [error] uncaughtException: read ECONNRESET
2026-02-08T22:48:53.895Z Error: read ECONNRESET
2026-02-08T22:48:53.896Z [info] [Socket-Manager] Client telnet connection closed. Emitting 'mudDisconnected'
mystiker commentedon Feb 9, 2026
Update / Umsetzung in PR #170
Der PR setzt zwei zentrale Gegenmaßnahmen gegen die Azure‑Idle‑Disconnects um:
Socket.IO Keepalive explizit konfigurieren
Server nutzt jetzt
pingIntervalundpingTimeoutaus Env‑Variablen, um die WS‑Verbindung aktiv zu halten und Azure‑Idle‑Timeouts zu vermeiden.TCP Keepalive für Telnet aktivieren
Die Telnet‑TCP‑Verbindung sendet Keepalive‑Probes (TELNET_KEEPALIVE_DELAY) – das verhindert, dass Azure/Proxies eine idle TCP‑Verbindung resetten.
Zusätzlich gibt es einen Fallback auf eine neue Session, falls Socket.IO endgültig nicht reconnecten kann, um “hängende” Sessions nach Server‑Restart zu vermeiden.
Warum löst das das Problem?
Der beobachtete ~4‑Minuten‑Disconnect ist sehr wahrscheinlich ein Infrastruktur‑Idle‑Reset (Azure App Service). Durch regelmäßige WS‑Pings und TCP‑Keepalive bleibt die Verbindung aktiv, sodass Azure nicht aus Idle‑Gründen trennt. Falls dennoch ein Resume scheitert, erzwingt der Client eine frische Session statt in einem defekten Zustand hängen zu bleiben.