# Zeitgleiche Kommunikation, mögliche Ansätze



## editOr (16. Jul 2011)

Hallo zusammen

Ich stehe vor folgender Herausforderung. Im Rahmen meiner Bachlorarbeit in VWL möchte für ein Experiment ein kleines Tool entwickeln, das es ermöglicht, dass ca. 20 Leute ein kleines, sehr einfaches Spiel gegeneinander spielen.

Vereinfacht stelle ich mir das wie folgt vor:
Jeder Spieler sitzt (im gleichen Raum) vor einem separaten Computer (Internetanschluss und Netzwerk vorhanden). Auf jedem Screen ist eine Eingabefeld.  Spieler 1 gibr nun z.B. den Text "Hallo" im Eingabefeld ein. Dieser Wert erscheint dann möglichst zeitgleich auf allen anderen Bildschirmen (Spieler 2-20). Diese können darauf reagieren, indem sie beispielsweise einen Button drücken. Wichtig dabei ist auch die Reaktionsgeschwindigkeit der Spieler. D.h., ist Spieler 4 der erste der den Button drückt, wird seine Aktion ausgeführt, die Aktionen der späteren Spieler werden nicht mehr ausgeführt.

Das Timing resp. das gleichzeitige erscheinen der Medlung auf den Bildschirmen ist also essentiell. 

Meine Frage:
Wie würdet ihr sowetwas angehen. Ich bin in keiner Weise eingeschränkt. Ich dachte schon daran, dies mit php und ajax zu lösen, kann mir aber auch ein kleines Java-Programm vorstellen. In beidem habe ich Erfahrungen mit kleineren Anwendungen, aber genügend Zeit, mir die nötigen Kenntnisse anzueignen. In Java habe ich mir z.B. RMI bereits angeschaut. Die Komplexität des Spiels, das ich anstrebe ist ähnlich wie oben beschrieben sehr einfach, kritisch ist lediglich die zeitgleiche Kommunikation zwischen den Spielern. 

Wie würdet ihr soetwas angehen? (Java, Website, anderes?) 
Ist es überhaupt möglich, oder der Ansatz zu blauäugig und ohne grosse Erfahrung nicht umsetzbar?
So nicht beanwortbar?

Bin froh um kurze Feedbacks und mögliche Stichworte.

Viele Grüsse
Michael


----------



## Matthias K. (18. Jul 2011)

Hi Michael,
ich steige zwar gerade erst in die Netzwerk-Programmierung ein, 
würde aber folgenden Ansatz wählen:
Ein Computer ist der Server des Spiels auf dem sich alle Spieler einloggen.
Schreibt jetzt z.B. Spieler 1 "Hallo", wird dies an den Server weitergeleitet und dieser 
leitet es an alle angemeldeten Spieler (außer Spieler 1) weiter.
Da alle Computer ungefähr die gleiche Leistung haben, 
kommen die gesendeten Nachrichten praktisch Zeitgleich (für einen Menschen nicht unterscheidbar) an.
Dieses Verfahren würde ich dann ebenfalls für den Knopfdruck nutzen.
Ich habe auf meinem Computer zum Einstieg einen lokalen Server erstellt und
diesen mit einem Client kommunizieren lassen. Dies ist meiner Meinung nach nicht besonders komplex und gut umsetzbar. 
Wie dies genau in einem Netzwerk aussieht weiss ich leider nicht.
Jedoch denke ich, dass man sich nur noch mit Zugriffsrechten rumschlagen muss.
Alles in allem ist es meiner Meinung nach gut umsetzbar und vorallem wird keine ewige Planung benötigt, weil das Ziel sehr simpel ist.

Ich hoffe ich konnte helfen.

Gruß,
Matthias


----------



## bERt0r (19. Jul 2011)

Im endeffekt ist das was du suchst eine simplere Version eines Chat programms: Der Operator darf schreiben, alle andern halt nur auf den Knopf drücken. Ein Tutorial von sowas findet sich sicher irgendwo im Netz, weil schon zig tausendmal gemacht.


----------



## Andi_CH (19. Jul 2011)

Wenn es echt zeitkritisch ist darfst du nicht mit IP kommunizieren sondern musst auf UDP setzten, allerdings mit dem Risiko, dass einer der Spieler das Datenpaket nicht bekommt.

so auf die Schnelle:

- Server läuft und horcht
- Clients starten und melden sich beim Server an
- Server bestätigt die Anmeldung
- Client schickt eine Meldung
- Server empfängt Meldung
- Server schickt Meldung an alle
- Server empfängt Reaktionen und merkt sich die Zeiten
- X Sekunden nach dem Versenden erstellt der Server die Rangliste
- Server verteilt die Rangliste

Keine Ahnung ob das in etwa dein Problem umschreibt, aber wenn nicht bringt es dich vielleicht auf die Idee wie du dein Problem etwas zerlegen könntest.


EDIT: Habe gerade noch das da gefunden ...


----------



## ice-breaker (19. Jul 2011)

Deine Echtzeit-Anforderung ist nur durch die Netzwerklatenz limitiert.
Ein TCP-Ansatz (am leichtesten) wird auch nicht großartig anders als ein UDP-Ansatz sein.

Deine minimale Latenz ist aber durch folgende Formel gegeben:

```
Latenz = RTT Sender + RTT Empfänger

RTT = Round Trip Time (Ping)
```
In einem Netzwerk mit einem Ping von 1ms wird dementsprechend eine Nachricht von Spieler A zum Server und von Server A zu allen Spielern jeweils ungefähr 2ms benötigen. Übers Internet mit einem Ping von 40ms sind wir also immernoch bei nur 80ms, also unter einer Zehntelsekunde, das sollte denke ich für deine Echtzeit vollkommen ausreichen.

Fazit: Um die Echtzeit musst du dir mit Java TCP Sockets keine Gedanken machen.


----------



## tuxedo (19. Jul 2011)

ice-breaker hat gesagt.:


> In einem Netzwerk mit einem Ping von 1ms wird dementsprechend eine Nachricht von Spieler A zum Server und von Server A zu allen Spielern jeweils ungefähr 2ms benötigen. Übers Internet mit einem Ping von 40ms sind wir also immernoch bei nur 80ms, also unter einer Zehntelsekunde, das sollte denke ich für deine Echtzeit vollkommen ausreichen.
> 
> Fazit: Um die Echtzeit musst du dir mit Java TCP Sockets keine Gedanken machen.



Kann dir zu 50% zustimmen. Wenn man den Nagle-Algorithmus auf dem Socket abschaltet, dann geht das ziemlich schnell und es wird für vieles reichen. Allgemein kann man aber nicht sagen dass TCP UDP in nichts nachsteht was die Geschwindigkeit betrifft. 80ms sind auch in Echtzeit-Übertragungen nicht ohne. Bei einer Audio oder Videoübertragung merkt man 80ms recht deutlich. Die 80ms Latenz nerven da ziemlich. Und bei etwa 150ms ist das ganze nicht mehr auszuhalten. 
Es kommt also drauf an was du überträgst und wie du es überträgst. Wenn du nur nen Mausklick übertragen willst, dann sind wohl auch 200ms noch okay. 

- Alex


----------



## FArt (19. Jul 2011)

Das meiner Meinung nach ist alles viel zu technisch (low level), für deine Anwendung erst mal irrelevant.

Dem Javaentwickler würde ich den Tipp geben, eine gute API zu verwenden, z.B. Apache MINA oder JBoss Netty. Damit kann man schnell und einfach einen Broadcast (das ist es ja eigentlich, was du machen möchtest) realisieren. Das darunter liegende Protokoll ist konfigurierbar und erst mal zweitrangig.

Einem unerfahrenen VWLer würde ich sagen: wenn du technisch (und in der Programmierung) begabt, interessiert und ehrgeizig bist, bekommst du das hin. Sonst ist das eher ein wenig zu hoch gegriffen.


----------



## editOr (23. Jul 2011)

Vielen Dank für die Inputs

Tatsächlich sagt mir der Unterschied von UDP und TCP grundsätzlich (noch) nichts. 
Ich verstehe das aber so, dass wenn ich das übers Netzwerk (nicht Intenet) umsetze, die Latenz egal bei welchem Protokoll kein Problem sein wird. Werde mich einmal einmal mit Mina und Netty auseinandersetzen

Auf die Gefahr hin, dass das eine dumme Frage ist, die mich als absoluten Anfänger outet: Wo ist "RMI" in diesem Zusammenhang einzuordnen? (Damit habe ich nun ein kleines funktionierendes Chat-Programm hingekriegt.)


----------



## Gregorrr (23. Jul 2011)

VWL (Volkswirtschaftslehre)? Warum bezahlst du nicht jemanden 100 €, der das für die mal schnell programmiert? Das ist ja nicht das Kerngebiet deines Fachs...?


----------



## editOr (23. Jul 2011)

Ja, ist Volkwirtschaftslehre. Jemanden zu zahlen ist ne Möglichkeit, da mich die Sache aber auch interessiert, wende ich gerne etwas Zeit auf, mir das selbst beizubringen.:rtfm:

Nachtrag: Einiges googlen hat gezeigt, dass RMI auf TCP aufbaut, dementsprechend sicher langsamer ist. Ob problematisch langsamer konnte ich noch nicht herausfinden.

Um meine Frage damit selbst zu beantworten (oder zumindest zu versuchen): RMI ist eine Vereinfachung basierend auf TCP, ähnlich wie Mina und Netty eine Vereinfachung - wenn auch mit mehr Konfigurationsmöglichkeiten - darstellen.


----------



## Gregorrr (24. Jul 2011)

ice-breaker hat gesagt.:


> Deine Echtzeit-Anforderung ist nur durch die Netzwerklatenz limitiert.
> Ein TCP-Ansatz (am leichtesten) wird auch nicht großartig anders als ein UDP-Ansatz sein.
> 
> Deine minimale Latenz ist aber durch folgende Formel gegeben:
> ...



IMHO, ist (fast) vollkommen egal, was für ne Latenzzeit herrschst. Was man braucht ist eine richtige Uhrensynchronisation.

Es ist doch so: Du willst die Reaktionsgeschwindigkeit von den SPIELERN haben - und nicht von dem NETZWERK. D.h. übers Netzwerk wird nur die Logik der Auswertung übertragen. Das wichtigste passiert auf den einzelnen Computern:

Sei gegeben: Recher A-Z, Spieler A-Z, Übertragungszeit Netzwerk: 2h (übertrieben), Uhrensynchronisation.
1. Rechner A-Z gleichen die Uhren miteinander aus (wird bei 2h etwas Zeit dauern, hahhahhahhah :lol
2. Runde beginnt, sagen wir um 14.00 Uhr
3. Spieler E ist erster um 14.01 Uhr, usw. F braucht 14.05
4. Nach 2 h (Latenzzeit des Netzwerks) kommt das Ergebnis an: 
5. Auswertung: E_Reaktionszeit = 0.01, F_Reaktionszeit = 0.05 => E hat gewonnen, weil seine lokale Reaktionszeit nur 0.01 betragen hat, aber das ist ja unabhängig von der Übertragungszeit die für die Auswertung gebraucht wurde...

Könnte natürlich sein, dass ich etwas an den Requirements übersehen hab, aber von der Logik her ists IMHO total unerheblich wie die Latenzzeit ist zur Auswertung des Ergebnisses.

[Klar ist die Latenzzeit wesentlich für die Berechnung der Uhrensynchronisation, aber ab dem Zeitpunkt, wo man das abgeglichen hat, ist die Zeit RELATIV.]


----------



## Empire Phoenix (24. Jul 2011)

Denke dafür kann man sich den aufwand der uhrensynch sparen,wenn das in einem lokalen Netzwerk ist, ist das unrelevant. Im beug auf die Problemstellung.

Als einstieg würde ich mir an deienr Stelle anschauen wie diverse beispeiel eines Chat Servers aufgebaut sind. Im wensetlichen musst du nir die Gui des Clients verändern dass der kein eingabefeld hat, sondern einen Button der einen vorgefertigten text schickt "player 1 clicked" oder so.
Netzwerklatenz sollte lokal unter allem liegenw as relevant ist. (Menschliche gehirn wird weit über 2 ms brauchen somit irrelevant) (man könnte jetzt noch damit ankommen, dass alle auch die selbe maus haben müssen von wegen physicalischer verzögerung ^^)


----------



## Gregorrr (24. Jul 2011)

Empire Phoenix hat gesagt.:


> Denke dafür kann man sich den aufwand der uhrensynch sparen,wenn das in einem lokalen Netzwerk ist, ist das unrelevant. Im beug auf die Problemstellung.
> 
> Als einstieg würde ich mir an deienr Stelle anschauen wie diverse beispeiel eines Chat Servers aufgebaut sind. Im wensetlichen musst du nir die Gui des Clients verändern dass der kein eingabefeld hat, sondern einen Button der einen vorgefertigten text schickt "player 1 clicked" oder so.
> Netzwerklatenz sollte lokal unter allem liegenw as relevant ist. (Menschliche gehirn wird weit über 2 ms brauchen somit irrelevant) (man könnte jetzt noch damit ankommen, dass alle auch die selbe maus haben müssen von wegen physicalischer verzögerung ^^)



Uhrensynchronisation ist vollkommen übertrieben, stimmt.

+1


----------



## Wildcard (25. Jul 2011)

Wenn der Client dem Server die Zeitdifferenz zwischen Empfangen der Daten und Userreaktion übermittelt hast du auf sehr einfache Art die Netzwerklatenz aus der Gleichung eliminiert.
Der Server entscheidet den 'Gewinner' nicht daran wer als erster das Datenpaket schickt, sondern wer die kleinste Zeitdifferenz (also die tatsächliche Reaktionszeit) überträgt.
Auf diese Art spielt weder die Latenz, noch asynchrone Uhren zwischen Server und Client eine Rolle und du musst dich auch nicht mit UDP rumschlagen.
Ich gehe mal davon aus das für deinen Fall ein 'gehackter' Client der bei der Differenz betrügt keine Rolle spielt.


----------



## xehpuk (27. Jul 2011)

Ich würde das auch einfach über TCP lösen. Sollte innerhalb eines Netzwerks Latenz wirklich eine Rolle spielen (ist nur halb rhetorisch gemeint, bin kein Experte, daher interessiert mich das "wirklich")? Dann könnte der Server ja jedes Mal, wenn Spieler 1 eine Nachricht geschickt hat, vor der Benachrichtigung der anderen Spieler erst mal einen Ping schicken, welcher beim Ankommen von den Clients sofort beantwortet wird, und dann die Zeitdifferenz berechnen. Würde natürlich auch unverfälschte Clients voraussetzen.



Andi_CH hat gesagt.:


> Wenn es echt zeitkritisch ist darfst du nicht mit IP kommunizieren sondern musst auf UDP setzten, allerdings mit dem Risiko, dass einer der Spieler das Datenpaket nicht bekommt.


Statt IP war hoffentlich TCP gemeint. Ohne IP wirds mit UDP auch schwierig.


----------



## akimoon (4. Aug 2011)

Das mit dem Ping finde ich immernoch zu kompliziert. Am einfachsten ist es doch, ein "Start-Event" auszulösen (zum Beispiel zeitgleich mit dem Anzeigen der Buttons & des Textes?) welches einen Timer startet. Bei Klick auf einen Button wird der Timer beendet und die Zeit an den Server geschickt?
Somit wäre es doch egal, wielang das Paket braucht und wie der Client an Zeit konfiguriert ist, oder übersehe ich irgendwas?

Ein Timeout sollte natürlich eingebaut werden, damit der Server nicht ewig wartet? ^^


----------



## muckelzwerg (4. Aug 2011)

Ähm, was hat das denn mit Netzwerklatenz zu tun?
Der Server versendet ein Signal an alle Teilnehmer.
Jeder Client bekommt dieses Signal. Jeder Client zeigt das Signal an und stempelt mit seiner lokalen Uhr die aktuelle Zeit. 
Jeder Client wartet darauf, dass der Benutzer reagiert, oder irgendein Abbruch stattfindet.
Sobald der Benutzer den Knopf drückt, oder was anderes tut, stempelt der Client wieder mit seiner Lokalen Uhr.
Die Zeitdifferenz entspricht der Reaktionszeit des Benutzers.
Die wird an den Server geschickt und der kann dann schauen, welcher Benutzer der schnellste war.


Bei einem lokalen Netz, solltest Du keine Probleme damit bekommen, dass die Probanden das Signal aus der Reaktion eines anderen Spielers ablesen, bevor es erscheint.
Ansonsten müssen die Sichtbereiche abgetrennt werden, oder Du lässt die Signale nicht sofort, sondern zu einem bestimmten Zeitpunkt in der Zukunft ausführen und synchronisierst die Uhren der Rechner mit NTP. (gibts vom BS geschenkt)


Geh einfach von einem einzelnen Probanden aus. Da würdest Du doch auch lokal messen. Wenn Du mehrere Probanden hast, misst Du immernoch lokal. Übers Netz synchronisiert wird dann nur der Ablauf des Programms, nicht aber die Messung.
In einem "normalen" LAN sollte für einen Menschen als Beobachter immernoch so gut wie alles "gleichzeitig" ablaufen.


----------



## bERt0r (6. Aug 2011)

Soll das ganze dann ungefähr so ausehen, oder ist einer der Quiz-Master und alle andern müssen Antworten?

ImageShack® - Online Photo and Video Hosting

Ich hab es mit Multicasting gelöst, die Spieler ignorieren neue "Reaktionstests" wenn bereits einer am laufen ist bzw.reagieren sie nicht auf "Responses" wenn kein Test läuft. Ist allerdings kein Test am laufen, kann jeder Spieler einen neuen Test starten. Der Spieler der den Test gestartet hat, kann auch selbst darauf reagieren.
Der Vorteil ist, dass es relativ einfach ist und die gleichzeitige Kommunikation am besten garantiert wird, der Nachteil ist, dass durch den dezentralen Aufbau Unsicherheiten entstehen. Wenn du für dein Spiel mehr Kontrolle haben willst, wer was wann darf und eventuell auch noch irgendwelche Punkte mitzählen willst, wirst du mit einem Client-Server Ansatz wohl glücklicher werden.


----------

