# Client/Server: Auf Antwort warten?



## Angel4585 (14. Dez 2007)

Hallo,

kleine Frage zum Programmierstil:

Ich hab ne Client Server Anwendung und schicke jetzt ein Objekt vom Client an den Server.

Nun soll der Server auf der selben Verbindung mir eine Antwort schicken. Allerdings soll mein Client auf diese Antwort warten und nicht nach dem versenden des Objektes an den Server einfach weitermachen.
Wie mache ich das am Besten? 
Eine Extra Socketverbindung öffnen die diese "Abfrage" abarbeitet, oder die vorhandene Verbindung nehmen? Aber wie mache ich das am Besten bei nur einer Socket-Verbindung??


----------



## tuxedo (14. Dez 2007)

Hmm, kann es sein dass du den Wald vor lauter Bäumen nicht mehr siehst?

Wenn der Client auf eine Antwort warten soll, dann muss der Thread, der sich mit der Netzwerkkommunikation beschäftigt, mit einem blockierenden Read auf eine Antwort warten. 

Ich nehme an du benutzt NIO mit non-blocking?

- Alex


----------



## Angel4585 (14. Dez 2007)

genau, nio mit non-Blocking.

Ich habe einen Thread der auf Anfragen vom Server wartet und fordere nebenher über die selbe Socketverbindung Daten an.

Wenn ich Daten anfordere soll das Programm solang warten bis die da sind.

Wie gesagt, momentan geht das alles über eine Verbindung.

Allerdings wäre es auch gut wenn direkt in dem Frage-Thread auch das Ergebnis kommt und ich dann dort auch weiterarbeiten könnte, anstatt das ich ne Anfrage raus schick, den Frage-Thread beende, im Thread der den Eingang kontrolliert dann ne Antwort bekomm und wieder einen Thread starte der die Antwort auswertet. Das wär ein kompliziertes jonglieren denke ich.

Wie löst du/ihr das?
Mehrere Verbindungen wären ja machbar, nur dauert das Herstellen der Verbindung immer ewig, oder?


----------



## tuxedo (14. Dez 2007)

Ich glaub den Client kannst du ruhig im Blocking-Betrieb fahren. Am Server ist das ja was anderes bei vielen Verbindungen.

Am Client liegt es halt an dir eine "Ich schicke eine Frage und warte dann auf die Antwort"-Schicht zu implementieren. Ist also eher eine Designfrage.

AUSSER das Frage-Antwort-Spiel läuft asynchron und mehrere Fragen können rausgehen, worauf für jede Frage auf eine Antwort gewartet wird, jedoch in beliebiger Reihenfolge. Dann müsstest du die Antwort vom Server irgendwie kennzeichnen "ich bin die Antwort auf Frage XYZ". Aber auch hier ist das mit einer entsprechenden Schicht im Design kein Problem.

Wenn du bei non-blocking bleibst, dann kannst du mit einer Schleife wieder künstlich blocken bis die Antwort eingetroffen ist.

- Alex


P.S. Ich würde RMI benutzen. Aber da ist ja die Sache mit dem Callback etc. Und mein eigenes RMI, welches das "Problem" nicht hat, ist noch nicht einsatzbereit.


----------



## Angel4585 (14. Dez 2007)

Also von RMI will ich momentan weg, weil die Sache mit dem Callback in einer anderen Anwendung die ich noch entwickle leider eine Bedingung ist und ich nicht zwei Anwendungen mit unterschiedlichen "Technologien" entwickeln möchte.

Ausserdem soll es tatsächlich so sein, dass mehrere Fragen raus gehn, und die Antworten in unterschiedlicher Reihenfolge zurückkommen. Aber ich hab da grad ne Idee, ich werd wohl ein IDObject erzeugen welches bei jedem anderen Object mit- und zurückgeschickt wird. Das werd ich die Tage  mal testen


----------



## tuxedo (14. Dez 2007)

Weiß ja nicht wie deine "Frage" und "Antwort" aussieht. Aber ich würde ein generelles Transportobjekt bauen. Eine Klasse von der alle "Fragen" und "Antworten", sowie alles was halt über's Netz geht erbt. 

In der Klasse kannst du dann Nachrichtentyp und ID verankern. Dann einfach das Objekt via DataOutputStream versenden (oder halt selbst serialisieren). Auf der anderen Seite dann halt lesen, und wieder in das Transportobjekt casten. Dort kannst du dann anhand des darin enthaltenen Nachrichtentyps entscheiden, welche Art von Objekt es denn genau ist (Frage, Antwort, sonstwas) und das dann in das entsprechende, endgültige Zielobjekt casten.

RMI wäre halt für sowas prädestiniert. Bin mir mittlerweile sicher, dass eine Lib die eine RMI-Funktion zur verfügung stellt und dabei nur eine Socketverbindung nutzt und demnach auch über diese eine Socketverbindung Callback-fähig ist, in solchen Anwendungsgebieten, reißend absatz finden würde ... ;-)

- Alex


----------



## Angel4585 (14. Dez 2007)

Ich hab momentan ein Interface "Sendable" das von Serializable abgeleitet ist und auch direkt die serialVersionUID beinhaltet.
Von diesem Sendable leite ich alle weiteren Objekte ab die ich versenden will.


----------



## tuxedo (14. Dez 2007)

Angel4585 hat gesagt.:
			
		

> Ich hab momentan ein Interface "Sendable" das von Serializable abgeleitet ist und auch direkt die serialVersionUID beinhaltet.
> Von diesem Sendable leite ich alle weiteren Objekte ab die ich versenden will.



Ja, das ist doch schon was. Wobei die serialVersionUID ja primär erstmal nur für's serialisieren gut ist.

Du könntest halt sowas hier machen:


```
class TransferObject implements Sendable {

private int transferType = 0;
private int transferID = 0;

public static final int TRANSFERTYPE_QUESTION = 0;
public static final int TRANSFERTYPE_ANSWER = 1;
public static final int TRANSFERTYPE_OTHER = 2;

public void setTransferType(int type){
this.transferType = type;
}

public void setTransferID(int ID){
this.transferID = ID;
}

public int getTransferType(){
return this.transferType;
}

public int getTransferID(){
return this.transferID;
}

}
```

Wenn alle deine übertragenen Objekte davon erben, hast du einen gemeinsamen Nenner und kannst sowohl Serverseitig als auch clientseitig mit der selben Klasse arbeiten und musst dann nur noch, entsprechend der TransferID in eine Zielklasse casten.


----------

