Rundenbasiertes Client-Server-Kartenspiel - Unicast (TCP) oder Multicast (UDP)

8

Ich plane derzeit ein Kartenspielprojekt, bei dem die Clients über Nachrichten, die über Sockets gesendet werden, rundenbasiert und synchron mit dem Server kommunizieren. Das Problem, das ich habe, ist, wie ich mit dem folgenden Szenario umgehen soll:

(Der Client ist an der Reihe und sendet seine Aktion an den Server.)

  1. Der Client sendet eine Nachricht, in der er dem Server seinen Zug für den Zug mitteilt (z. B. spielt er die Karte 5 aus seiner Hand, die auf den Tisch gelegt werden muss).

  2. Der Server empfängt Nachrichten und aktualisiert den Spielstatus (der Server hält den gesamten Spielstatus).

  3. Der Server durchläuft eine Liste der verbundenen Clients und sendet eine Nachricht, um sie über Statusänderungen zu informieren

  4. Alle Clients werden aktualisiert, um den Status anzuzeigen

Dies alles basiert auf der Verwendung von TCP, und wenn man es jetzt betrachtet, scheint es ein bisschen wie das Observer-Muster zu sein. Der Grund, warum dies für mich ein Problem zu sein scheint, ist, dass diese Nachricht nicht wie die anderen Punkt-zu-Punkt-Nachrichten zu sein scheint, da ich sie an alle Clients senden möchte, und dass das Senden derselben Nachricht nicht sehr effizient ist dieser Weg.

Ich habe darüber nachgedacht, Multicasting mit UDP zu verwenden, da ich dann die Nachricht an alle Clients senden könnte. Würde dies jedoch nicht bedeuten, dass die Clients theoretisch in der Lage wären, sich gegenseitig Nachrichten zu senden? Es gibt natürlich auch den synchronen Aspekt, obwohl dies, denke ich, über das UDP gestellt werden könnte.

Grundsätzlich würde ich gerne wissen, was eine gute Praxis wäre, da es bei diesem Projekt wirklich nur ums Lernen geht, und obwohl es nicht groß genug ist, um auf Leistungsprobleme zu stoßen, möchte ich sie trotzdem in Betracht ziehen.

Bitte beachten Sie jedoch, dass ich nicht daran interessiert bin, nachrichtenorientierte Middleware als Lösung zu verwenden (ich habe Erfahrung mit der Verwendung von MOM und bin daran interessiert, andere Optionen außer MOM in Betracht zu ziehen, wenn TCP-Sockets eine schlechte Idee sind!).

LDM91
quelle

Antworten:

11

Nicht vorzeitig optimieren. Halte es einfach. Die Verwendung von TCP ist in diesem Fall in Ordnung, und ich sehe keine Probleme mit Ihrem aktuellen Schema.

UDP wird normalerweise für leistungskritische Szenarien verwendet, z. B. in einem Online-Actionspiel, da es die explizite Kontrolle über einzelne Pakete ermöglicht, anstatt auf einer Schichtabstraktion von Streams wie TCP zu arbeiten. Obwohl Sie einen gewissen Geschwindigkeitsgewinn erzielen, indem Sie genau steuern, wie Daten gesendet werden sollen, behandelt UDP Paketverlust oder Paketbestellung nicht wie TCP. In diesem Fall müssen Sie sie selbst codieren. Da es sich also um ein rundenbasiertes Kartenspiel handelt, bezweifle ich, dass Sie die Zuverlässigkeit gegenüber der Geschwindigkeit opfern möchten. Verwenden Sie also TCP.

XiaoChuan Yu
quelle
Vielen Dank für Ihre Antwort, es war klar und scheint alles zu beantworten, was ich gefragt habe.
LDM91
3

Selbst viele große, beliebte MMOs verwenden ausschließlich TCP. Es wird alles tun, was Sie brauchen, mit allen Effizienzmerkmalen, die Sie benötigen.

UDP erfordert viel zusätzliche Komplexität, Multicast erfordert noch mehr Komplexität, und Sie werden nichts daraus machen. Wenn Sie nur am Lernen interessiert sind, stellen Sie auf jeden Fall eine Tech-Demo für sich selbst zusammen, aber denken Sie nicht, dass das Projekt selbst in irgendeiner Weise besser dran sein wird.

Wenn Sie überhaupt an UDP interessiert sind, besteht Ihre allererste Aufgabe darin, TCP zusätzlich zu UDP neu zu implementieren, um sicherzustellen, dass Sie tatsächlich verstehen, wie Sie mit allen Problemen umgehen, die TCP für Sie löst: Überlastung Kontrolle, erneute Übertragung verlorener Pakete, verzögerte doppelte Verarbeitung, Paketbestellung, zuverlässiger Handshake der Verbindung, zuverlässige Trennungssequenz usw.

Es ist nicht unbedingt schwierig, all diese Probleme zu lösen, aber es erfordert ein tiefes Verständnis der Vernetzung, des IP-Protokolls und der Art und Weise, wie diese Probleme gelöst werden.

Von dort aus beginnt der Spaß beim Aufbau der Bibliothek, um Funktionen anzubieten, die TCP fehlen. Verwenden eines über einen Paketstrom gemultiplexten Nachrichtenstroms, effizientere Überlastungskontrolle, Behandlung von Ratenbegrenzungen, Mehrkanäle, Kanalkonfiguration (ob der Kanal Nachrichten in der richtigen Reihenfolge erfordert oder nicht, ob verworfene Pakete zulässig sind usw.) usw.

Ich würde vorschlagen, dass Sie die folgende Artikelserie lesen. Es ist nicht perfekt und macht einige sehr fragwürdige Behauptungen (beginnend mit dem Unsinn "TCP niemals in Spielen verwenden"), aber seine technischen Details sind für neue Netzwerkprogrammierer hilfreich: http://gafferongames.com/networking-for-game- Programmierer / udp-vs-tcp /

Sean Middleditch
quelle
1
In der Einleitung zu diesem Artikel erklärte der Autor: "Die Wahl, die Sie treffen, hängt ganz davon ab, welche Art von Spiel Sie vernetzen möchten. Von diesem Punkt an und für den Rest dieser Artikelserie gehe ich davon aus, dass Sie dies möchten Sie kennen Spiele wie Halo, Battlefield 1942, Quake, Unreal, CounterStrke, Team Fortress und so weiter. "
XiaoChuan Yu
Ah, das habe ich verpasst, als ich es überflogen habe, um sicherzugehen, dass es so gut ist, wie ich es mir erinnere. Es tut mir leid.
Sean Middleditch
-1 für "Wenn Sie überhaupt an UDP interessiert sind, besteht Ihre allererste Aufgabe darin, TCP zusätzlich zu UDP neu zu implementieren" , ist IMO sehr falsch. Viel nützlicher, um zu lernen, wie UDP tatsächlich Dinge tut, für die UDP ausgewählt wird.
o0 '.
@ Lohoris: Das ist nicht hilfreich und nicht einmal richtig. Sie MÜSSEN auch mit UDP in der Lage sein, garantierte Nachrichten in der richtigen Reihenfolge zu senden. Sie müssen in der Lage sein, nicht garantierte Nachrichten in der Reihenfolge zu senden. Sie müssen in der Lage sein, garantierte Nachrichten außerhalb der Reihenfolge zu senden. Es ist am einfachsten, mit dem TCP-ähnlichen Verhalten zu beginnen, da alle erforderlichen Funktionen implementiert werden müssen und am einfachsten zu testen sind. Selbst für sich genommen bieten sich nützliche Funktionen wie eine direktere Kontrolle der Bandbreitennutzung und der Latenz.
Sean Middleditch
@ Seanmiddleditch falsch. Es ist nichts falsch sowohl UDP und TCP in dem gleichen Spiel mit der Verwendung, so dass Sie nicht sind erforderlich eine garantierte Lieferung über UDP zu implementieren.
o0 '.