Socket lesen mit DevIo: Wie tote Verbindung erkennen?

Begonnen von gvzdus, 06 Februar 2021, 15:09:18

Vorheriges Thema - Nächstes Thema

gvzdus

Wir haben gerade etwa 3 Seiten im OBIS-Modul-Thread gefüllt. Situation: OBIS-Zähler wird über ser2net - also eine TCP-Verbindung - ausgelesen. "Stecker ziehen und neu Einschalten" auf der ser2net-Seite hat daher zur Folge, dass die Verbindung "ewig" hängt, weil FHEM mangels Schreibzugriffen nicht merkt, dass die Verbindung tot ist.
Ob jetzt SO_KEEPALIVE per Default vom OS gesetzt wird oder nicht: Da nur global parametrisierbar und per Default zu langsam (Stundenbereich), ist das keine schöne Lösung.

DevIo_SimpleReadWithTimeout ist nicht jugendfrei, da blockierend.

Meine Überlegung: Minütlicher "cronjob" im Modul, der prüft, ob in den letzten X Sekunden etwas reingekommen ist und ggf. nach Ablauf Close/Open macht.

Oder wäre eine allgemeine, nicht modul-spezifische Lösung in DevIo sinnvoller?
Das Problem ist m.E. ein sehr allgemeines für die ReadOnly-TCP-Verbindungen ohne Keepalive als Protokoll-Element.

rudolfkoenig

DevIo setzt fuer Netzverbindungen SO_KEEPALIVE, leider ist das Intervall nur OS-weit regelbar, und ist etwas ueber zwei Stunden per Voreinstellung (unter Linux siehe /proc/sys/net/ipv4/tcp_keepalive_*).

Eine FHEM weite Loesung hat zwei Probleme: das akzeptable Intervall, wo keine Daten empfangen werden, muss pro Modul gesetzt werden, und es muesste eine neue Schnittstelle definiert werden, da ReadFn z.Zt. beim Aufruf davon ausgehen kann, dass sysread nicht blockiert.

Ich preferiere eine moduleigene Loesung. Falls die Gegenstelle auf Anfrage antworten kann, dann ein regelmaessiges Ping (wie bei MQTT), sonst ein Timer, was im ReadFn zurueckgesetzt wird.

Oder Geduld haben: das Problem wird im Mittel nach einer Stunde entdeckt.
Wenn man den Stecker selbst gezogen hat, dann kann man FHEM neu starten, oder die Verbindung per "set XX reopen" wieder oeffnen. Spart einen weiteren Timer.

gvzdus