android asynchrone sockets (android app als server, die auf verbindungen von clients wartet)

  • Hi,


    ich arbeite derzeit an einem projekt für die uni und könnte eure hilfe gebrauchen.
    Auf stackoverflow hab ich meine Frage eben auch schon gepostet, ich hoffe mal das ist kein Problem? (zumal es sich dort größtenteils um englische user handelt)
    Ebenfalls bin ich auf androitpit aktiv, was hoffentlich auch kein problem ist. Bin durch Zufall vorhin auf das Forum hier gestoßen und hoffe hier mehr Hilfe zu finden was Android Development angeht.
    Ich denke es macht so mehr Sinn, da nicht alle Leute dort vorbeischauen, die hier aktiv sind.
    Somit würde es sicher auch anderen Entwicklern hier helfen :-).


    Im Projekt haben wir vor eine tcp socket verbindung zu nutzen, um eine android app und einen client auf windows kommunizieren zu lassen.
    Der client soll nachher ein Spiel sein, welches durch die App gesteuert werden kann. Durch die Sensoren unter Android kann man sich da eine schöne Steuerung basteln :-). (Kurzfassung ohne Code, befindet sich unten :-D.)


    Die MainActivity startet einen Service, welcher sich um den Aufbau eines ServerSockets kümmern soll und allgemein um die gesamte Verbindung. Meine App soll in dem Zusammenhang der Server sein, welcher Verbindungen entgegennimmt.


    Ich werde nun im folgenden die wichtigsten Codeausschnitte posten und hoffe das jemand den "Fehler" findet :-/, bzw. mir einfach helfen kann.


    Service Klasse:


    Die ConnectionHandler Klasse ist wie folgt implementiert:


    Der ConnectionHandler und die ConnectionWriting-Klasse sind als AsyncTasks implementiert, sodass die blockenden Funktionen von TCP nicht meine gesamte Anwendung blockieren und beeinflussen.


    Wichtig zu wissen ist noch, dass der Client auch Nachrichten an den Server schicken kann. Natürlich weiss man nicht, wann eine solche Nachricht geschickt wurde, sodass ich irgendwie den Stream dauerhaft beobachten muss. Ich habe das jetzt hier als TimerTask realisiert, welcher alle 10ms ausgeführt wird und guckt ob Nachrichten vorhanden sind.


    Diese Klasse sieht wie folgt aus:


    Und die Klasse die zum Schreiben von Nachrichten an den Client benutzt wird, sieht wie folgt aus:



    Diesen komplexen, asynchronen Ansatz habe ich eben deshalb gewählt, da der Server (die app) durchgängig Daten an den Client sendet, es dazwischen allerdings Fälle geben kann, in denen der Client auch dem Server etwas senden will, was ich unbedingt möglichst zeitnah erhalten muss.


    Die eigentlich funktionsweise von tcp sockets sieht ja so aus, dass das lesen und schreiben gegenseitig blockierend sind. Das würde eben dazu führen, dass ich die Nachrichten des clients nie erhalten würde, zumindest nicht so lange wie ich (der server) daten an den client sendet.


    Kurzfassung:
    Mein Ansatz scheint nicht wirklich asynchron abzulaufen. Ich habe zum Test mal direkt nach erfolgreicher Verbindung 100 Nachrichten an den Client gesendet, die ich mit einem Echo direkt beantworte. Im Log sieht man, dass der Server zuerst alle seine Nachrichten abschickt und dann erst die vom Client gesendeten liest :-/. Also genau das was ich nicht haben wollte.


    Eventuell kann mir einer helfen dieses Problem zu lösen?
    Ich habe so viele verschiedene Ansätze und Vorschläge im Internet gelesen, allerdings sind mir bei vielen noch mehr Fragen aufgekommen, sodass ich mich eben für eine eigene Lösung entschieden habe.


    Wichtig ist: Die Kommunikation muss asynchron sein! Ebenso muss das Lesen automatisch immer wieder stattfinden, also quasi das Lauschen auf ein Read muss irgendwie implementiert werden können.


    Ein interesseanter Ansatz, von dem ich gelesen habe, geht in die Richtung, dass man für das Lesen und Schreiben jeweils einen Thread nimmt. Das Problem hierbei ist aber, dass ich nicht weiss wie ich dann aus meinen Activities die Threads nutzen kann um was zu schreiben und wie ich aus den Threads Funktionen in meinen Activities aufrufen kann.


    Für jeden Hinweis wäre ich sehr dankbar.


    LG

  • Hi,


    ich bin mit einem Kollegen auch zur Zeit dabei eine Client-Server Applikation bei uns an der FH zu entwickeln. Wir haben bei uns das ganze auch mit Threads gelöst.
    Da du die Threads in mehreren Activities brauchst und es sinvoll wäre nur eine Instanz davon zu haben, könntest du das Singleton-Pattern anwenden und die Thread-Instanz in jeder Activity holen, in der es benötigt wird. Zu mindest für den schreibenden Thread wäre das eine Lösung.


    Was sind das für Nachrichten und was sind das für Funktionen die in den Activities aufgerufen werden sollen? Ich kann mir das noch nicht so ganz vorstellen.


    Aber vllt hilft dir der erste Ansatz schonmal.


    block_

  • Ich habe es jetzt auch mit Threads gelöst, allerdings ein wenig anders.
    Im Hintergrund läuft ein Service, welcher von allen Activities ganz einfach gebindet werden kann und falls ich meine Activities benachrichtigen muss, sende ich einen Broadcast-Intent. So kann ich sogar entweder an alle Activities etwas senden oder eben nur an eine oder mehrere. Das Threading funktioniert jetzt auch und durch die Priorisierung wird der lesende immer bevorzugt behandelt, was bei uns halt wichtig ist.


    LG

Jetzt mitmachen!

Sie haben noch kein Benutzerkonto auf unserer Seite? Registrieren Sie sich kostenlos und nehmen Sie an unserer Community teil!