Ausführen von Server und Client im selben Prozess

9

Frage

Ich habe gerade zum ersten Mal angefangen, mit Lidgren und dem Netzwerk zu arbeiten, und bin zu der Erkenntnis gekommen, dass es möglich ist, sowohl den Server als auch den Client innerhalb desselben Prozesses auszuführen .

Wird diese Praxis aus irgendeinem Grund entmutigt?

Kontext

Der Grund, den ich frage, ist, dass ich theoretisiert habe, dass dieses Konzept es mir ermöglichen könnte, sowohl den Einzelspieler- als auch den Mehrspielermodus als ein und denselben zu behandeln, was sehr hilfreich wäre.

Diesem Gedanken folgend, ist dies die Verteilung, an die ich gedacht habe:

  • Einzelspieler - 1 Server + 1 Client im selben Prozess. Wie schnell ist die Kommunikation?
  • Multiplayer - Wie Einzelspieler für den Host + 1 zusätzlicher Client für jeden anderen Spieler.

Der von mir dargestellte Ausführungsablauf dient dazu, dass Clients Benutzereingaben empfangen und eine Benachrichtigung an den Server senden. Anschließend überprüft der Server dies und sendet eine Aktion, die von allen Clients ausgeführt werden soll. Es sollte keine Rolle spielen, ob es nur einen Client (dh Einzelspieler) oder mehrere Clients (dh Mehrspieler) gibt.

David Gouveia
quelle

Antworten:

7

Dies ist im Grunde eine Frage zwischen Prozess und Thread. Beide sind nicht zu unterschiedlich. Manchmal werden Threads als Lightweight-Prozesse bezeichnet. Der größte Unterschied besteht darin, dass ein separater Prozess einen eigenen Adressraum hat, es jedoch andere Unterschiede gibt (1):

Pro Prozess

  • Adressraum
  • Globale Variablen
  • Dateien öffnen
  • Untergeordnete Prozesse
  • Ausstehende Alarme, Interrupts und Signalhandler

Pro Thread

  • Programm zähler
  • Register
  • Stapel
  • Zustand

Aufgrund dieser Unterschiede kann es nützlich sein, einen Server- und einen Client-Thread im selben Prozess zu haben, damit Sie Dateihandles und globale Variablen gemeinsam nutzen können. Dies wäre ein Argument für den Ansatz "Im selben Prozess". Ein weiteres (kleines) Argument wäre, dass Sie nur ein Popup-Fenster "Windows-Firewall" pro Prozess erhalten. Ein Argument für den Ansatz "Unterschiedlicher Prozess" wäre, dass eine Person mehrere Server ausführen kann, ohne mehrere Clients ausführen zu müssen. Dies wäre ideal für einen engagierten Host wie Setup und ist ein Ansatz, den wir üblicherweise bei Ego-Shootern sehen.

Was nun die Idee betrifft, einen Serverprozess oder -thread auch für das Offline-Spiel (und vielleicht sogar für Einzelspieler) zu haben, ist dies eine großartige Idee, die in der Praxis häufig verwendet wird. Sie können sagen, dass viele Spiele dies tun, indem Sie auf den Ladebildschirm schauen. Kleine Hinweise wie "Empfangen" verraten es. Es ist logisch, dies zu tun, da die meisten Spielregeln, wenn Sie einen Mehrspieler-Modus erstellen möchten, vom Server geregelt werden. Warum also nicht für Einzelspieler? Dies reduziert den Code, den Sie schreiben müssen, und sorgt für eine klarere Trennung zwischen Client und "Spiel", wodurch Ihre Codequalität verbessert wird.

Wie wäre es nun mit der Kommunikation zwischen Prozessen und Threads? Prozessübergreifende Kommunikation kann auf viele Arten erfolgen, (Named-) Pipes, Shared Memory, COM, es hängt wirklich von der Technologie ab, die Sie verwenden. Wenn Sie jedoch einen Server erstellen, möchten Sie wahrscheinlich eine Netzwerkvariante mit Sockets und ähnlichem wie TCP verwenden. Hier ist LIDGREN natürlich hilfreich.

Viele dieser Techniken gelten auch für die Thread-übergreifende Kommunikation. Dies hängt jedoch noch mehr von den verwendeten Techniken ab. Sie könnten wieder mit TCP arbeiten, aber vielleicht wäre ein noch einfacheres System Ereignisse und etwas Marshalling, obwohl dies Ihre Spielschleife nicht deterministisch machen könnte (2).

Quellen

  1. Entwurf und Implementierung von Betriebssystemen (MINIX-Buch), 3. Auflage von Andrew S. Tanenbaum
  2. Korrigieren Sie Ihren Zeitschritt von Glenn Fiedler: http://gafferongames.com/game-physics/fix-your-timestep/
Roy T.
quelle
1
Meine einzige Ergänzung ist, dass Sie möchten, dass der lokale Client nahtlos mit dem lokalen Server zusammenarbeitet und denselben Code wie die Remote-Clients verwendet, und dass dieser Client denselben Code erneut verwendet, um eine Verbindung zu einem Remote-Server herzustellen, zu dem Sie gehen 1) Verwenden Sie einen Prozess für den Server und 2) Verwenden Sie das Netzwerk, da dies der gemeinsame Nenner ist. Es sei denn, Sie möchten zwei Versionen Ihres Transportcodes schreiben =)
Patrick Hughes