2 Stimmen

Fragen zur Abstraktion und Client/Server-Architektur für ein Python-Spielprogramm

Hier ist mein derzeitiger Stand der Dinge. Ich entwerfe ein Kartenspiel mit dem Ziel, wichtige Komponenten für die zukünftige Arbeit zu nutzen. Der Teil, der mich aufhält, ist die Schaffung einer Abstraktionsebene zwischen dem Server und dem/den Client(s). Ein Server wird gestartet, und dann können ein oder mehrere Clients eine Verbindung herstellen (lokal oder aus der Ferne). Ich entwerfe einen Thick Client, aber mein Freund möchte einen webbasierten Client entwickeln. Ich möchte den Server so gestalten, dass eine Vielzahl verschiedener Clients einen gemeinsamen Satz von Serverbefehlen aufrufen kann.

Für den Anfang möchte ich also einen "Server" erstellen, der die Spielregeln und die Interaktionen der Spieler verwaltet, und einen "Client" auf dem lokalen CLI (ich verwende der Einfachheit halber Ubuntu Linux). Ich versuche herauszufinden, wie die beiden Teile interagieren sollen, ohne zu verlangen, dass zukünftige Clients CLI-basiert oder auf dem lokalen Rechner sein müssen.

Ich habe die folgenden zwei Fragen gefunden, die nützlich sind, aber die obigen Fragen nicht ganz beantworten.

Ich benötige nicht sofort einen vollständigen Funktionsumfang, sondern möchte nur die grundlegenden Abstraktionsmechanismen festlegen, damit der resultierende Mock-up-Code die Beziehung angemessen widerspiegelt: Bei einer Client/Server-Beziehung sind andere Annahmen im Spiel als bei einer All-in-One-Anwendung.

Wo soll ich anfangen? Welche Ressourcen können Sie empfehlen?

Haftungsausschlüsse: Ich bin mit Code in einer Reihe von Sprachen und allgemeinen Programmier-/Logikkonzepten vertraut, habe aber wenig Erfahrung mit dem Schreiben größerer Mengen von Code. Dieses Lieblingsprojekt ist ein Versuch, dies zu korrigieren.

Ich weiß auch, dass es diese Informationen bereits gibt, aber ich habe den starken Eindruck, dass ich den Wald vor lauter Bäumen nicht sehe.

2voto

S.Lott Punkte 371691

Informieren Sie sich über RESTful-Architekturen.

Ihr Fat Client kann REST verwenden. Er verwendet urllib2 um RESTful-Anfragen an einen Server zu stellen. Es kann Daten in JSON-Notation austauschen.

Ein Web-Client kann REST verwenden. Er kann einfache Browser-HTTP-Anfragen stellen oder eine Javascript-Komponente kann komplexere REST-Anfragen mit JSON stellen.

Ihr Server kann als einfache WSGI-Anwendung unter Verwendung beliebiger einfacher WSGI-Komponenten erstellt werden. Es gibt gute Komponenten in der Standardbibliothek, oder Sie können die Werkzeug . Ihr Server nimmt einfach REST-Anfragen entgegen und gibt REST-Antworten. Ihr Server kann in HTML (für einen Browser) oder JSON (für einen Fat- oder Javascript-Client) arbeiten.

2voto

Alex Martelli Punkte 805329

Ich würde in Erwägung ziehen, alle Server/Client-Interaktionen auf HTTP zu stützen - wahrscheinlich mit JSON-Payloads. Dies erlaubt nicht direkt Server-initiierte Interaktionen ("Server-Push"), aber der (neuartige, aber bereits traditionelle;-) Workaround dafür ist AJAX-y (auch wenn das X wenig Sinn macht, da ich JSON-Payloads vorschlage, keine XML-Payloads;-) -- der Client initiiert eine asynchrone Anfrage (über einen separaten Thread oder anderweitig) an eine spezielle URL auf dem Server, und der Server antwortet auf diese Anfragen, um (in der Praxis) "Pushes" durchzuführen. Nach dem, was Sie sagen, sieht es so aus, als ob die Einschränkungen dieses Ansatzes kein Problem darstellen würden.

Der Hauptvorteil der Spezifikation der Interaktionen in solchen Begriffen ist, dass sie völlig unabhängig von der Programmiersprache sind - so wird der webbasierte Client in Javascript genauso machbar sein wie Ihr CLI in Python, usw. usw. Natürlich kann der Server als Sonderfall auf localhost laufen, aber dafür gibt es keine Einschränkung, da die HTTP-URLs jeden beliebigen Host angeben können, auf dem der Server läuft; usw. usw.

2voto

jscharf Punkte 5639

Zunächst einmal kommunizieren Sie unabhängig von Ort und Art des Kunden über eine etablierte nachrichtenbasierte Schnittstelle. Alle Clients arbeiten auf der Grundlage eines gemeinsamen Satzes von Anfragen und Antworten, und der Server wird diese je nach ihrer Gültigkeit entsprechend dem Spielstatus bearbeiten oder zurückweisen. Ob es sich dabei um lokale Clients auf demselben Rechner oder um Remote-Clients über HTTP handelt, spielt vom Standpunkt der Abstraktion aus gesehen keine Rolle, da sie alle über denselben Satz von Anfragen/Antworten kommunizieren werden.

Es geht darum, dass Ihr Protokoll . Ihr Protokoll sollte eine klar definierte und technisch solide Sprache zwischen Client und Server sein, die es den Clients ermöglicht, a) effektiv und b) fair teilzunehmen. In diesem Protokoll sollte festgelegt werden, welche Nachrichten ("Moves") ein Client wann ausführen kann und wie der Server darauf reagieren wird.

Ihr Protokoll sollte vollständig ausgearbeitet und dokumentiert sein, bevor Sie mit der Spiellogik beginnen - die beiden sind untrennbar miteinander verbunden, und Sie ersparen sich eine Menge Zeit und Mühe, wenn Sie Ihr Protokoll zuerst genau definieren.

Ihr Protokoll ist die Abstraktion zwischen Client und Server und dient auch als Entwurfsdokument und Programmierleitfaden für beide.

Beim Entwurf von Protokollen dreht sich alles um Zustände, Zustandsübergänge und Validierung. Spieleserver haben in der Regel eine Reihe von ziemlich allgemeinen, generischen Zuständen für jede Spielinstanz, z. B. Initialisierung, Lobby, Gameplay, Pause, Rekapitulation, Spiel beenden, etc.

Zu jedem dieser Staaten gibt es wichtige staatliche Daten. Ein "Lobby"-Zustand auf der Serverseite könnte zum Beispiel den bekannten Zustand jedes Spielers enthalten... wie lange es seit der letzten Nachricht oder dem letzten Ping gedauert hat, was der Spieler gerade tut (einen Avatar auswählen, Einstellungen ändern, zum Kühlschrank gehen usw.). Das Organisieren und Verwalten von Zustands- und Unterzustandsdaten im Code ist wichtig.

Die Verwaltung dieser Zustände und der damit verbundenen Datenanforderungen ist ein Prozess, der sorgfältig geplant werden sollte, da sie in direktem Zusammenhang mit dem Arbeitsvolumen und der Projektkomplexität stehen - dies ist sehr wichtig und auch eine gute Übung, wenn Sie dieses Projekt als Einstieg in größere Dinge nutzen wollen.

Außerdem müssen Sie bedenken, dass, wenn Sie ein Spiel haben und die Leute spielen lassen, die Leute schummeln werden. Das ist eine Tatsache des Lebens. Um dies zu minimieren, müssen Sie Ihr Protokoll und Ihre Zustandsverwaltung sorgfältig entwerfen, um nur gültige Zustandsübergänge zuzulassen. Vertrauen Sie niemals einem einzigen Client-Paket.

Für jede Permutation des Client/Server-Zustandes müssen Sie eine begrenzte Anzahl gültiger Spielnachrichten erzwingen, und Sie müssen sehr vorsichtig sein, was Sie den Spielern erlauben und wann Sie es ihnen erlauben, es zu tun.

Die Projektkomplexität ist im Allgemeinen exponentiell und nicht linear - die Programmierung von Client/Server-Spielen ist in der Regel ein guter/schmerzhafter Weg, dies zu lernen. Gute Frage. Ich hoffe, das hilft, und viel Glück!

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X