Socket Socket Verbindung wiederherstellen

Stroker89

Bekanntes Mitglied
Hallo,

ich habe eine Android App (Client) und einen Konsoloenprogramm (Server) die miteinander per Sockets kommunizieren.
Die Verbindung ist bidirektional und funktioniert soweit einwandfrei.

Jetzt zu meiner Frage:
Angenommen Client verliert kurzzeitig seine Internetverbindung, gibt es dann eine Möglichkeit dass der Server das merkt und ein erneutes Verbinden auf diesem Socket zulässt, ohne dass man der Socket auf der Serverseite neu erstellen muss.

Jeder Socket läuft auf dem Server in einem eigenen Thread. Wird der Socket vom Client geschlossen, so wird auch der Thread beendet.

Gruß Martin
 
Das gestaltet sich eher als schwer, da der Client sich verbindet sobald die App startet und sich erst wieder verabschiedet, wenn die App geschlossen wird. Das neu Verbinden gestaltet sich also nicht ganz so einfach...
 
Wenn sich die Internetverbindung trennt fliegt beim Lesezugriff normalerweise eine Exception. Diese kannst du dann eben behandeln indem du neu verbindest.
 
ich denke die frage zielt eher darauf ab ob es möglich wäre bei verlust der verbindung diese zu re-etablieren als ob diese nie getrennt gewesen wäre ...

an sich ist das so nicht direkt möglich ...

ein lösung wäre das sowohl client als auch server ihre daten in einem speziellen objekt halten was für die kommunikation zu ständig ist ...

bricht nun die verbindung ab kann man ein timeout verwenden nach dem dann endgültig gesagt wird "verbindung unterbrochen" ...
kann aber während dieser zeit die verbindung wieder hergestellt werden (also der client baut eine neue TCP-verbindung zum server auf) muss der server anhand von header daten prüfen ob es dazu ein objekt gibt und gibt dann an das noch "laufende" objekt einfach den neuen socket / die neuen streams ...

der client merkt davon nichts da dieser nur anfragen gegen das verbindungs-objekt richtet was innerhalb des timeouts die daten einfach in einen buffer schreibt und bei erfolgreicher wiederherstellung einfach sendet ...
sowohl server als auch der client müssen dann lediglich so ausgelegt sein das beim read() nicht direkt eine exception kommt (oder zumindest nicht gleich weitergereicht wird) sondern erstmal während des timeouts (bzw bis zu dessen ablaufen) versucht wird die verbindung wieder aufzubauen und erneut read() auszuführen ...

in wie weit java einem da mit der api hilft weis ich jetzt nicht aus dem kopf ... aber ich denke wenigstens etwas, nämlich die zuordnung einer neuen verbindung zu einem bestehenden objekt, muss man schon selbst basteln ...


an sich also grob gesagt : ja, wäre schon so möglich, müsste man aber einiges selbst implementieren
 
Wenn mit Verbindungsunterbrechungen öfters zu rechnen ist, dann würde ich das wie ein "Pseudo-Semipermanentes Pseudo-Stateless Protokoll" (also ähnlich wie HTTP mit KeepAlive) implementieren.

1) Client kommt an, bekommt eine Session-ID zugewiesen

2) Unter dieser Session-ID speichern Client wie Server die notwendigen Daten lokal

3) Bei der Kommunikation wird immer die Session-ID als erstes Übertragen, dann der Rest der Daten.

3) Bricht die Verbindung ab, wird sie einfach neu aufgemacht und mit der die alten Session-ID weitergearbeitet.

Alles natürlich nicht ganz trivial, da Du aber dein eigenes Protokoll definieren kannst wirds nicht ganz so brutal wie bei HTTP.

Bernd
 
gut ... mit dauer-polling würde es auch gehen ... aber du hast einiges vergessen

1) mit deiner lösung wäre der server nicht in der lage a-synchron zum poll des clients diesem daten zu schicken ... vielleicht ist dies aber erwünscht / notwendig ...
man könnte es zwar so regeln das der server auf den nächsten poll wartet ... aber wenn realtime nötig ist scheidet das aus ...
außerdem sollte man eine permanente verbindung einem polling vorziehen

2) erhöter traffic durch overhead und geschwindigkeits-engpässe
wenn man alleine den overhead nimmt den es kostet immer wieder eine verbindung neu aufzubauen und wieder zu trennen kommt man über einen gewissen zeitraum auf ne ganze menge "datenmüll"
ist zwar in der heutigen zeit zu vernachlässigen ... aber dennoch sollte man sowas nicht unbedacht lassen ... vor allem wenn es um mobile geräte geht bei denen nicht sichergestellt werden kann wie wofür gezahlt wird ... denn nicht jeder hat eine flatrate
außerdem würde die geschwindigkeit aufgrund TCP Slow Start leiden ... wofür ja als gegenmaßnahme extra mit HTTP/1.1 KeepAlive eingeführt wurde ... um mal bei deinem beispiel zu bleiben ...

3) sollte man polling nutzen stünde man immer noch vor dem problem des verbindungs-abbruches ...
wenn die verbindung weg ist bevor der poll beginnt fängt man dies einfach ab und wartet den zyklus bis zum nächsten ab ...
was aber wenn die verbindung genau während der daten-übertragung wegbricht ? ergebnis : man steht wieder am anfang des problems und hat sich sinnloser weise damit beschäftigt sein system von einer permanent verbindung in eine polling-geschichte umzubauen ...

an sich ist die idee für die low-level schicht nicht ganz verkehrt ... aber doch einfach zu allgemein und für das einsatzgebiet von TO dann doch eher weniger geeignet
 
Also die Kommunikation findet bidirektional statt. Eine weitere Anforderung ist, dass der Server mehrere tausend Verbindungen gleichzeitig verwalten muss. Auch soll die Kommuikation via XML statt finden, also ein eigenes Protokoll. Da wären wir auch schon beim nächsten Problem...
Hab damit leider gar keine Erfahrung...:-(

Gruß Martin
 
Vieleicht erzählst du erstmal was du so vorhast. Ich Bezweifle dass XML die beste Lösung ist, kommt aber immernoch drauf an was geplant ist.
 
Die Vorgabe ist eine XML Kommunikation über Sockets. Die Verbindung passt jetzt soweit. Ob eine wiederverbindung der Clients später implementiert wird ist noch nicht klar, da es eine sehr sicherheitskritische Anwendung wird.

Das wiederherstellen einer Verbindung hat mich nur rein technisch interessiert ob sowas überhaupt möglich wäre.

Die einfache Kommunikation über Strings steht bereits, also der Server behandelt mehrere Clients sehr gut (Threads leben nur so lang wie die Verbindung steht). Client ist eine Android App.

Mein Problem ist jetzt vorrangig das XML Protokoll und wie ich es implementiere.
Mir stellen sich momentan so Grundsatzfragen wie z. B. wie speichern die Teilnehmer den Status der Verbindung. Also an welcher Stelle der Kommunikation sich die Teilnehmer befinden. Wie sehen dazu Best Practises aus. Man findet leider nur sehr spärliche Informationen im Netz zu diesem Thema.

Gruß Martin
 
Ich weiß dass XML kein Protokoll ist ich meinte damit auch das XML basierende Protokoll das ich entwerfen und entwickeln soll.

@Bernd: Könntest du mir das bitte erklären?
 
@Bernd: Könntest du mir das bitte erklären?

Die Daten innerhalb von Android sind nicht sonderlich gut bis garnicht gegeneinander abgeschirmt. Sollte Deine App also Daten auf der "internen Festplatte" des Telefons ablegen kann das durch andere Apps problemlos gelesen werden (sofern der Benutzer zugestimmt hat - und wer macht das nicht?).

Eine fehlerfreie, permanente Datenübertragung via GPRS/UMTS/Sonstwas mit einem Mobiltelefon ist so einfach wie Fliegen mit Esstäbchen zu fangen. Ausserhalb dieser kleinen Alleskönner kann man das mit VPN (zb. OpenVPN) regeln welche den Socket über längere Zeit quasi freischwebend und blockierend auflassen können bis man wieder connected hat. Gibts auch für Android, aber dazu muss man root werden und das geht im Standard nicht.

Ich halte Android für ein nettes OS auf dem Sachen laufen mit denen ich mir im Wartezimmer eines Arztes die Zeit vertreiben kann. Vitale Daten würde ich darauf nicht publizieren, im Rufnummernspeicher hab ich nur die Nummern meiner Feinde.

Bernd
 
Auf dem Gerät selber werden keine Daten gespeichert außer eine Art Benutzername. Sämtliche Daten bekommt das Gerät vom Server. Selbst einen Großteil der Config. Diese App wird ohne Internetzugang gar nicht benutzbar sein.

Gruß
 

Zurück
Oben