Socket-Reconnect bei Verbindungsabbruch

gamp

Mitglied
Hallo,

Ich versuch mich neuerdings auch ein bißchen mit Java und hab mir als "Start-Projekt" gedacht einen kleinen Channel-Service-Bot fürs IRC zu schreiben.
Jedoch hab ich jetzt folgendes Problem:
Ab und an, wirklich selten aber dennoch passiert es, disconnected der Bot aufgrund von "PING TIMEOUT".
Was ich jetzt einbauen will - und zwar IMMER wenn er disconnected, nicht nur bei "PING TIMEOUT" sondern immer, egal welchen Grund es hat, ist eine "Reconnect" funktion, quasi sobald die Verbindung abgebrochen wurde (aus welchem Grund auch immer) soll er den alten Socket schließen und selbst eine neue Verbindung herstellen. Eine Möglichkeit hab ich auch schon umgesetzt, is allerdings nicht wirklich schön; bei "PING TIMEOUT" sendet der Server eine Zeile "ERROR: ... (Ping Timout)", also nehm ich das eben als Indikator um den alten Socket zu schließen und eine neue Verbindung zum Server herzustellen.

Was mir quasi fehlt ist ein Indikator der anzeigt "Hey, die Verbindung ging gerade Verloren!", damit ich sobald das auftritt den Neustart-Vorgang einleiten kann.

Bei google hab ich einiges gefunden, vor allem so ne Art Timer, der einen Timeout setzt wenn der Server einige Zeit nichts gesendet hat, dann den Socket schließt und eine neue Verbindung aufbaut. Leider hab ich das alles nicht so richtig verstanden, also lange Rede kurzer Sinn:

Kann mir wer ein Beispiel geben, bei dem zB. eine Exception einen Verbindungsabbruch zum Server meldet, die ich dann "catch'en" und in das Scope der Exception meinen "Reconnect-Vorgang" einbauen kann? Oder irgendeine andere eventuell bessere Möglichkeit? Ein kurzes Beispiel wäre nett!

Vielen Dank schonmal im Voraus.

Mfg,
gampoo
 
Hey Hey, naja wenn du es mit der Verbindung hinbekommen hast und Daten übertragen kannst, würd ich einfach ein "TTL-Paket" senden, da die Übertragungsart nicht aus Deinem Post hervorgeht, kann man jetzt auch nicht speziell darauf eingehen. Wie gesagt, eine Routine einbauen, die in einem bestimmten Zeitabstand ein Paket zum Server sendet, der entsprechend darauf reagiert, allerdings müsste bei einem Verbindungsabbruch sowieso 'ne Exception geworfen werden, musst sie halt nur in nem Catch-Block auffangen. MfG
 
Danke für die Info!
Hab nochmal mehr recherchiert;

Scheinbar gibt es bei TCP/IP nicht wirklich ne Möglichkeit um über eine funktion den Status vom Socket abzufragen, also ob er noch Connected oder bereits Timed-Out ist. Eine Möglichkeit wäre KEEP_ALIVE zu setzen, jedoch checkt das (Ich glaube funktionsintern ist die KEEP_ALIVE genau das was du beschrieben hast, ein TTL-Packet-Check) die Verbindung abhängig vom verwendeten Betriebssystem nur alle paar Stunden, bei Linux zB alle 2 Stunden.

Mein Problem war quasi das der Server den Client schon "rausgeworfen" hat, da er keinen PONG von diesem in einem bestimmten Zeitintervall erhalten hat, was dazu führte das der Client dann in der while(bufferedreader.readLine() != null) fest hing und sich da zu Tode geloopt hat. Er hat quasi unendlich lang, vergeblich auf weitere Mitteilungen vom Server gewartet. Zwar teilt der Server dem Client über eine Zeile "ERROR: ... (Ping Timeout)" mit das er wegen fehlenden PONG-event gekickt wurde, jedoch war das ja nicht was ich verwenden wollte (es könnte ja zB. sein das eben diese Zeile nie beim Client ankommt).

Nach durchforsten etlicher Google-Resultate bin ich dann zu dem Schluss gekommen das ein Thread, das parallel zur readLine()-loop läuft die beste Möglichkeit ist. Also habe ich einen Timer erstellt, der jedesmal sobald ein PING vom server kommt auf 0 zurückgesetzt wird. Nehmen wir an der IRC-Server schickt meinem Client alle 120 Sekunden ein PING und ich ziehe zB. das Netzwerkkabel, dann wird mein Client eben diesen PING nichtmehr erhalten und nicht mit PONG drauf antworten. Antwortet er jedoch auf den PING nicht, so setzt er den Timer nicht auf 0 zurück. Überschreitet der Timer dann sagen wir 180 Sekunden so schlägt er Alarm "Hey, du hättest schon vor einiger Zeit einen PONG schicken müssen, dh. du hattest einen Timeout!" und ich kann hier dann meinen Code für den Reconnect einbauen.

Funktioniert prima!

EDIT: Sorry das ich beim 1. Post so ungenau war, wird nicht wieder Vorkommen ;-)

Mfg
gampoo
 
Zurück