Einzelnen Beitrag anzeigen
Alt 30.05.2014, 09:34   #19 (permalink)
flickflack
His Awesomeness!
10 Jahre hx3
5000 Beiträge
 
Benutzerbild von flickflack
 
Registriert seit: 25.07.2006
Ort: Regnum Borussiae
Beiträge: 9.282
Standard

Zitat von Poweruser Beitrag anzeigen

Den Trigger gibts, momentan lass ich, nachdem der Hauptthread dran war, prüfen, ob in der Queue noch was drinnen ist und wenn ja, wieviel. Ein zwanghaftes Abarbeiten wollte ich im Hauptthread unbedingt vermeiden, da man den Server damit zwingen könnte sich nur um UDP Pakete zu kümmern, was einem DoS für die TCP Verbindungen gleich kommt.
Man könnte das evtl in einem anderen Thread machen lassen, den man dann ja ruhig voll auslasten kann, allerdings muss man dann für Threadsicherheit sorgen und mit diesen Synchronisierungen bremst man dann bestimmt den Hauptthread aus.

Yep. Niemand mag Thread-Synchronisation. Kann ich voll nachvollziehen ^^

Zitat von Poweruser Beitrag anzeigen

Die Idee gefällt mir, vorallem würde man damit die Last vom Hauptthread auf den Empfängerthread verlagern, der eh noch nicht viel zu tun hat, außer zu empfangen und Bans zu prüfen. Ich bin aber immer noch dagegen sich den Inhalt der Pakete bei Überlastung anzuschauen. Viel mehr kann man hier, wenn man sich den Zeitpunkt des letzten Pakets merkt, recht einfach eine Empfangs-Geschwindigkeitsbegrenzung bauen. zB: Wer x Mal schneller als y Pakete/s gesendet hat, kommt auf die TempBanliste.
Da gibts allerdings dann wieder ein Problem: Wenn sichs im Empfangspuffer vom Betriebssystem schon staut, dann sind die Empfangszeiten in der Anwendung nicht mehr zuverlässig. Also muss der Empfangsthread den Puffer dort schneller leeren, als er sich füllt.

Ja, klar. Kommt halt auch immer auf das Protokoll an. Wenn sich das alles auch ohne DPI realisieren lässt, dann soll's so sein. Ich setze mir dann aber lokal trotzdem ne FW auf, die ne DPI macht ^^

Zitat von Poweruser Beitrag anzeigen

Nein, an die TCP Pakete in der Transportschicht kommt man nicht ran, da hat man nur Zugriff auf den Datenstrom. Bei UDP sollten die Pakete, die der Javasocket liefert, mit den anderen übereinstimmen, es sei denn die waren zu groß und mussten fragmentiert werden.

Ja okay, hab ich mir fast gedacht.

Zitat von Poweruser Beitrag anzeigen

Die Gameserver haben keine TCP Verbindungen, nur UDP (OFP zumindest, bei anderen Spielen: kA).
Das Senden von Heartbeats, Empfangen von Queries und Senden von Query-Antworten läuft alles über UDP hab.
TCP kommt erst beim Masterserver ins Spiel, wenn die Clienten die Serverliste anfordern.

Die Kommunikation zwischen Gameserver und Masterserver ist also lediglich UDP, und nur Gameclient und Masterserver kommunizieren via TCP? Okay, verstanden.


Zitat von Poweruser Beitrag anzeigen

Hier läuft das etwas anders ab. Wenn ein Client die Serverliste abfordert, dann bekommt er nur die IPs der Server, die sich bis dahin erfolgreich beim Masterserver registiert haben und momentan in der Serverliste stehen. Dabei findet kein Datenaustausch mit den Spielservern statt. Wenn ein Client den Status eines Spielservers erfahren möchte, dann soll er eine Query an den Spielserver schicken und nicht an den Masterserver. Der Masterserver unterstützt in dem Sinne auch gar keine eingehenden UDP Queries.

Juti, der Austauch von ein paar IPs ist sicher vernachlässigenswert. Ich bin trotzdem immer ein Freund davon, hier am Beispiel IP-Liste, die abzufragenden Daten im Vorfeld zu erstellen und nicht on-demand. Selbst das Durchforsten von Datenstrukturen kostet. Je nachdem wie hochfrequent und wie aktuell man sein möchte, bietet sich das eben an. Damit gibts nur eine Instanz die Last verursacht, nämlich der Scheduler. Jeder der fragt bekommt nur ne Auslieferung, ohne zuvor angeschlossene Abfrage. Aber wie gesagt, wenn Du das nicht für nötig hälst, ist das ja auch vollkommen in Ordnung. Du hast Dir da offensichtlich selbst genug nen Kopp gemacht.


Zitat von Poweruser Beitrag anzeigen

Bei jedem Statuswechsel (Erstellen, Warten, Mission laden, Besprechung, Spielen, Nachbesprechung) wird ein Heartbeat an den Masterserver geschickt:

Code:
\heartbeat\2303\gamename\opflashr\statechanged\1
Daraufhin sendet der Masterserver eine Query zurück und bekommt als Antwort eine etwas größere Nachricht, die etwa so ausschaut:
Code:
\gamename\opflashr\gamever\1.96\groupid\261\hostname\server_name\hostport\2302\mapname\island_name\gametype\mission_name\numplayers\0\maxplayers\20\gamemode\openplaying\timeleft\15\param1\0\param2\0\actver\196\reqver\196\mod\RES\equalModRequired\0\password\0\gstate\2\impl\sockets\platform\win\final\\queryid\2.1
Ah, der Statuswechsel sorgt also immer wieder für einen neuen "Handshake" mit dem Master, inklusive Statusaustausch. Verstehe. Der Heartbeat kommt nicht periodisch, sondern ist an Events gebunden? Bei denen sitzt bestimmt nen Observer auf dem Eventsourcing/Queue und guckt sich die Heartbeats an.Gar nicht mal soooooo doof von GS, warum geben die auf?

Zitat von Poweruser Beitrag anzeigen

Nein, das ist extakt die selbe Prozedur, mit der zB OFPMonitor die Informationen von den Spielservern abfragt. Außer, dass es für den Masterserver mehr oder weniger unnötig ist die Spielerinformationen abzufragen, weil er die nicht wirklich braucht.

Okay, aber er könnte die Infos pro Gameserver rausgeben? Vllt macht man hier noch eine Unterscheidung zum GS-Master und definiert gleich: Nö, ich gebe wirklich nur IPs zum Spiel. Den Rest kann die Implementierung machen.


Alles sehr spannend. Aktuell fällt mir nix mehr ein, was man noch beachten könnte/müsste. Macht'n guten Eindruck
flickflack ist offline   Mit Zitat antworten