Client Socket - Verhalten im Fehlerfall

Hallo Leute,

mir ist heute folgendes aufgefallen:
Situation: Ein IPS-ClientSocket stellt eine Verbindung zu einem entferntem Raspberry Pi her.

  • Wenn dieser Raspberry Pi rebootet wird so geht der IPS-ClientSocket relativ schnell auf Status 200 - gut so…
  • Wenn jedoch dieser Raspberry Pi plötzlich „weg“ ist, z.B. weil der Strom unterbrochen wurde, so geht der IPS-ClientSocket nicht in Status 200 sondern verbleibt fröhlich in Status 102.

Ist das so korrekt/gewollt?

Joachim

Grundsätzlich nicht falsch, weil ja die Gegenseite die TCP Verbindung nicht mehr beenden kann.
Sobald du jedoch versuchst Daten zu senden, sollte er sofort in Fehler gehen.
Wann das ohne Datentransfer passiert und wann bei welchen OS… keine Ahnung.
Weil das OS muss es ja auch erstmal erkennen, was ja nur geht wenn das Ziel nicht antwortet.
Hat dein Protokoll keinen KeepAlive um Verbindungsabbrüche zu erkennen?
Michael

…„mein“ ClientSocket erkennt es schon, hatte nur alles darauf aufgebaut, dass der IPS-ClientSocket es erkennt… war bisher nicht auf die Idee gekommen das Raspi mal komplett vom Netz zu nehmen, in meiner Welt war der Reboot Test genug - bin heute eines besseren belehrt worden.:stuck_out_tongue:
„Mein“ ClientSocket läuft dann in den TimeOut, müsste dann wohl selbst einen Timer installieren, der in diesem Fall jede Minute checkt ob die Verbindung jetzt wieder verfügbar ist um das Modul komplett neu durchzustarten…

Joachim

Das Neuverbinden macht IPS alleine alle 60 Sekunden, das brauchst du nicht selber umsetzen.
Auch den Status brauchst du nicht zyklisch prüfen, dafür reicht es doch auf IM_CHANGESTATUS im MessageSink zu reagieren.

Du musst nur zyklisch etwas senden damit der Socket überhaupt auch in Fehler geht.
Kannst das ja mit deinem PHP-Socket kombinieren.
Wenn du keine handle bekommst => einmal irgendwas über den Datenaustausch an den Pi senden.
Gibt es den ein Ping/Pong oder Keepalive im Protokoll ? Oder mußt du immer ‚Nutzdaten‘ übertragen.

Michael

…die Idee finde ich gut! Habe jetzt auf die Schnelle mal folgendes in „meinem“ ClientSocket eingebaut:

$this->Socket = @stream_socket_client("tcp://".$Host.":".$Port, $errno, $errstr, 5);
	if (!$this->Socket)
{$this->SendDebug("CommandClientSocket", "Fehler beim Verbindungsaufbau ".$errno." ".$errstr, 0);
						If ($errno == 10060) {
							$this->SendDebug("CommandClientSocket", "Fehler ".$errno, 0);
							$this->SetStatus(201);
							// Testballon über IPS-ClientSocket senden
							$this->ClientSocket(pack("L*", 17, 0, 0, 0));
						}

Aber irgendwie geht er schon nicht in die If-Bedingung…:confused:
Ist $errno ein String? Muss ich mal testen…

Joachim

…irgendwie stört es denn IPS-ClientSocket nicht einmal, wenn ich etwas über ihn sende wenn keine Gegenseite existiert…:mad:

Joachim

Das hört sich nicht gut an…bin aber der Meinung das ich das unter Windows nicht habe/hatte

Michael

…wenn ich schon den Hinweis aus dem „eigenen“ ClientSocket habe, dass etwas nicht in Ordnung ist, dann müsste man es doch irgendwie hinbekommen dass der IPS-ClientSocket in Status 200 geht wenn der das gleiche feststellt… (teste aktuell unter Windows)

Joachim

Jein… es ist ja ein Unterschied.
Du baust jedesmal die Verbindung neu auf mit TCP Handshake.
Bei dem IPS-Socket ist das schon erfolgt. Also meint das System die Verbindung ist noch da, wenn sich die Gegenseite nicht abmeldet. Du hast also eine halb offene Verbindung.
Aber wenn du jetzt Daten sendest, dann kommt ja keine Quittung auf TCP Ebene (ACK) und das sollte das OS und somit IPS schon merken.
Michael

…habe das jetzt noch mal auf einem Raspberry Pi probiert:
Der Splitter geht in den Status 201, der IPS-ClientSocket bleibt in 102…

Was würde wohl passieren, wenn ich per Code den IPS-ClientSocket auf Status 200 setze? Würde das funktionieren und danach der Reconnection-Versuch jede Minute gestartet werden?

Joachim

Du kannst keine Fremde Instanz in Fehler setzen.
Michael

…aber codeseitig trennen und wieder versuchen zu verbinden? Dann sollte der IPS-ClientSocket in Status 200 gehen?:confused:

Joachim

Ist aber der falsche Weg, man soll ja nicht die Instanzen umkonfigurieren.
Hört sich eher nach ein Bug in IPS an, wo es auf den Timeout des OS nicht reagiert.
Michael

@IPS-Team: Habt Ihr das mitgeschnitten oder soll ich das noch mal extra als Bug/Feature Anfrage stellen?:slight_smile:

Joachim

Auf welchem System läuft denn dein Modul? Auch auf einem Pi oder Windows?

Wir haben auf dem Pi auch schon beobachtet, dass die „Fehlerkennung“ länger dauert. Ich glaub bis zu 15 Minuten hat es mal gedauert, bis der Pi erkannte hatte, dass die Verbindung abgebrochen ist.

paresy

Hallo Paresy,

ich habe es auf beiden ausprobiert. Windows meldet dann wenn die Gegenstelle komplett weg ist (einfach Netzstecker zum Test gezogen) Fehler 10600 in „meinem“ ClientSocket, der Raspberry Pi komischerweise Fehler 110. Der IPS-ClientSocket geht aber bei beiden Systemen nicht in Status 200 (macht er relativ zeitnah bei einem sudo reboot).

Joachim

…hat das Thema jetzt den „Bug-Status“ oder ist es ein Feature-Request…:confused:

Joachim

Ich bin ein Leidtragender des Problems: nach einem größeren blitzschlagbedingtem Überspannungsschaden habe ich meine alte HW modernisiert und bin von AVR-IO’s auf RASPI’s umgestiegen.
Mein IPS Server läuft auf Windows, mehrere RASPI’s sind, über LAN verbunden, in der Haussteuerung tätig :Heizungsraum mit ca. 15 1-wire Temp Sensoren, Digital und Analog I/O’s zur Ansteuerung und zum Auslesen verschiedener Zustände, Außenbereich => Steuerung von Pool mit Solarerwärmung und Sauna, auch hier 1-wire, Digital und Analog I/O.
Wesentlich für meine Anwendung ist die automatische, sichere Wiederkehr des Systeme nach Stromausfall (haben wir hier leider ab und zu mal, ist halt ein gewitterträchtiges Gebiet). Bisher hatte ich das über die AVR-IO’s und entsprechende WatchDog Scripte gut im Griff.
Mit dem Umstieg auf die RASPI’s und Joachims Module hat sich das Verhalten der Client Sockets bei Stromausfall als Problem herausgestellt.
Ich bin brennend an einer zeitnahen Lösung (hoffentlich klappt das softwaretechnisch) interessiert damit ich in Ruhe meinen Urlaub genießen Kann :slight_smile:
Habt ihr schon Ideen zur Lösung?

Gruß, Michael

Hallo Paresy,

bei der hohen Anzahl an Baustellen sicherlich nicht von hoher Priorität, dennoch würde ich mir eine Rückmeldung wünschen, wie es in dieser Fragestellung weitergeht…:wink:

Joachim

Ich bin mir nicht sicher in wie fern das Problem direkt mit IP-Symcon zusammenhängen, oder ob das ein Kernel Parameter ist, der den Timeout vorgibt, bis ein Socket Tod ist. Da das Problem nicht „einfach mal schnell“ gelöst werden kann, vermute ich, dass eine Lösung auch etwas längern dauern wird.

paresy