Welche RESTful-API würdest du für einen rundenbasierten Spieleserver verwenden?

8

Wie würden Sie einen rundenbasierten Spieleserver als RESTful-API modellieren? Zum Beispiel einen Schachserver, auf dem Sie Schach gegen einen anderen Kunden derselben API spielen können. Du brauchst eine Möglichkeit, um ein Spiel mit dem anderen Kunden anzufordern und zu verhandeln, und eine Art, die einzelnen Spielzüge zu spielen.

Ist dies ein guter Kandidat für eine REST (RESTful) API? Oder sollte das anders modelliert werden?

    
Ross 01.01.2009, 22:34
quelle

10 Antworten

2

Welche Ressourcen möchten Sie modellieren? Ich würde vier haben: Sie, Ihr Gegner, das bestimmte Spiel (Sitzung, Instanz) und das Spielbrett. Also würde es mit etwas wie

anfangen %Vor%

Wir haben ein gutes Intro / einen Überblick über InfoQ .

    
Charlie Martin 01.01.2009, 22:46
quelle
4

Ich denke so etwas wie:

%Vor%

soweit die grundlegenden Ressourcen betroffen sind. Ich bin mir nicht sicher, wie ich mit dem "Hat der andere Spieler schon umgezogen?" Umgehen konnte. Idee, obwohl. Ich habe darüber nachgedacht, den GET-Anforderungsblock einfach zu halten, bis der Zug gespielt wird - d.h. Mein Klient würde die Koordinaten meines Zuges auf

setzen %Vor%

und dann würde GET

%Vor%

Der Server antwortet nicht sofort, sondern hält die Verbindung offen, bis der andere Spieler sich bewegt hat (d. h. PUT an diesen Ort). Ist das was Nakajima als "kometös" bezeichnet?

Charlie, ich bin mir nicht ganz sicher, was Sie mit dem "Token" gemeint haben, an wessen Seite es steht - löst das dasselbe Problem ohne die Notwendigkeit eines Pollings oder einer blockierenden Verbindung?

Ist es für Player-IDs sinnvoll, diese als Ressource in einem Teil der URL zu modellieren? Ich plante, einfach die HTTP-Benutzerauthentifizierung zu verwenden (wobei der Benutzer / Ausweis als Teil jeder Anfrage gesendet wird). Sie könnten immer noch die meisten Ressourcen ohne Authentifizierung abrufen, aber wenn Sie versucht haben, sagen Sie,

%Vor%

es würde Ihnen einen Fehler mit der Berechtigung verweigert geben, wenn Sie nicht die richtigen Zugangsdaten für dieses Spiel hätten.

    
Ross 02.01.2009 01:09
quelle
4

OK, die Grundidee von REST besteht darin, dass Sie den Status übertragen; Sie möchten wenig oder keinen "Sitzungsstatus" auf dem Server haben. Sie möchten also nicht den Sitzungszustand und Keepalive verwenden, was Comet tut. Aber denken Sie an das Beispiel eines Spiels per Post: Sie haben beide eine Kopie des Spielplans und Sie tauschen Züge aus. Die Post weiß nichts über das Spiel.

Nun, ich gebe zu, dass dies in meinen Gedanken wächst, wenn ich darüber nachdenke - in der Tat, ich könnte einen Artikel basierend auf dieser Frage schreiben - aber hier ist die Idee, wie einige Geschichten:

  1. Sie möchten eine Partie Schach spielen Linie, also gehst du zu einem bekannten URI zu nimm eins. Du bekommst eine Seite zurück zeigen wer, wenn jemand wartet um ein Spiel zu beginnen.
  2. Sie wählen einen der Wartenden aus zu spielen, und klicken Sie auf das entsprechende Verknüpfung. Sie erhalten eine neue Anzeige (Ajax Magie hier, wenn du willst) mit dem Board eingerichtet. Einer von euch ist weiß, Weiß bewegt sich zuerst.
  3. Wer das Recht hat sich zu bewegen, tritt ein eine Bewegung, und verpflichtet (wie nehmen deine Hand das Stück in einem Spiel.) Das Board aktualisiert und das Recht auf Bewegung geht zum anderen Spieler.

Sie brauchen nicht viel in Bezug auf den Server-Status --- obwohl Sie dies vielleicht erweitern möchten, indem Sie Bewegungen usw. verfolgen, sagen Sie für das Ranking - und die Frage, wer das Recht hat, sich zu bewegen, kann berechnet werden ganz von der Board-Seite: Wenn Sie das Recht haben, haben Sie ein Formular für die Eingabe eines Zuges; Wenn Sie die Rückgabe des Formulars zurücksenden, gibt die Antwort eine Seite ohne Slot für die Eingabe eines Zuges zurück.

Mit dem "Token" meine ich nur eine willkürliche Darstellung dieses einen Zustands des Zustands "My move" / "your move".

Scheint, als ob die benötigten Ressourcen

sind
  • Eine Startseite "Spiel finden"
  • Eine Benutzerseite, wenn Sie Statistiken verfolgen und so
  • eine eindeutige URI für jedes aktive Spiel.
Charlie Martin 02.01.2009 02:32
quelle
2

Danke, Charlie. Mir ist immer noch nicht klar, wie Sie über die Bewegung des Gegners in Ihrem Plan informiert werden. Natürlich kann die Frage, wer das Recht hat, sich zu bewegen, einfach berechnet werden - entweder von der Board-Ressource oder durch Verwendung einer separaten Ressource, die explizit angibt, an wen sie sich wenden soll. Aber wie weiß ein Kunde, dass sich diese Ressource geändert hat? Muss es einfach ständig abfragen und sich an den vorherigen Zustand erinnern, bis es bemerkt, dass sich etwas geändert hat? Im Post Office-Modell "pusht" die Post eine Nachricht an den Client (Ihr Postfach), was in HTTP nicht möglich ist.

Ich nehme an, dies ist Teil einer allgemeineren Frage: Wenn es eine REST-Ressource gibt, die ich auf Änderungen oder Modifikationen überwachen möchte, was ist der beste Weg, dies zu tun? Und gibt es etwas, was der Server tun kann, um dies für den Kunden einfacher zu machen?

Ich denke, ich werde das als eine separate Frage veröffentlichen, da ich denke, dass es von selbst interessant ist.

Bearbeitet, um hinzuzufügen: Was? ist eine REST-konforme Möglichkeit, eine REST-Ressource auf Änderungen zu überwachen?

    
Ross 02.01.2009 03:06
quelle
2

Ich denke nicht, dass REST eine gute Wahl für solch eine Anwendung ist. Die Transformationen und Operationen, die Sie ausführen müssen (verschieben, Verlauf anzeigen, rückgängig machen, Vorschlag abrufen, Benachrichtigung ändern), werden nicht gut auf das Ressourcenkonzept von REST abgebildet. (Die Schwierigkeiten sind vielleicht noch offensichtlicher, wenn man bedenkt, wie eine REST-API für kompliziertere Turn-basierte Spiele wie Scrabble oder Monopoly aussehen könnte.)

Ich denke, jede vernünftige REST-API würde wahrscheinlich ein Wrapper um etwas sein, das nicht REST-konform ist, wie etwa ein statusfähiges Protokoll, das portable gesendet hat Spielnotation hin und her.

    
mjs 17.05.2010 17:18
quelle
1

Ich denke, Sie könnten es RESTvoll modellieren . Implementierung wird schwieriger, weil Sie entweder einen Kometen benötigen) -esque Lösung oder Sie müssten den Server in einem relativ kurzen Intervall über AJAX abfragen.

Im Hinblick darauf, wie Sie eine REST-konforme Oberfläche bereitstellen würden, würde ich sagen, dass Sie ein Spielbrett mit Koordinaten, Teilen, die diese Koordinaten belegen können, und Aktionen, die diese Koordinaten ändern, benötigen.

Wenn ein Spieler einen Zug macht, wird eine neue Aktion erstellt. Nach der Überprüfung, um sicherzustellen, dass es zulässig ist, aktualisieren Sie den Status des Spiels und rendern dann die Antwort, die zum Aktualisieren der Benutzeroberfläche erforderlich ist.

Im Grunde genommen würde ich das so modellieren. Die Implementierungsseite ist jedoch, was ich hier als größere Schwierigkeit ansehe.

    
nakajima 01.01.2009 22:44
quelle
1
Ich glaube nicht, dass das alles so kompliziert ist, Nakajima. Sie würden Daten, sagen wir in JSON, für die Board-Position, für die Züge und mit einem Token für den nächsten Zug weitergeben. Es wäre genau so, als würde man per Post spielen.

Du beginnst damit, zum Spiel zu gehen und nach einem Partner zu suchen, also

%Vor%

gibt Ihnen eine Liste der Wartenden. Wenn du kommst, wenn niemand wartet, bekommst du eine Spiel-ID; Andernfalls wählst du jemanden aus, der wartet und erhalte die Spiel-ID, die sie haben.

%Vor%

zeigt dir das Board. Du brauchst etwas, um die Entscheidung zu treffen, wer weiß spielt, ich überlasse das als Übung. Die GET-Operation gibt Ihnen das Board, also sendet ein POST einen Zug; Wenn Sie die Bewegung nicht haben, erhalten Sie einen Fehler. Sie finden das Ergebnis beim nächsten GET.

Hölle, in diesem Modell benutze ich nicht einmal die Spieler-ID, obwohl es gut sein könnte, damit niemand sich als Kibitzer ins Spiel schleichen kann.

    
Charlie Martin 01.01.2009 23:01
quelle
1

Ihr Gedanke ist also, dass, anstatt die Aktionen zu einem erstklassigen Objekt zu machen, jede Bewegung als eine Aktualisierung des Spiels selbst betrachtet wird? Es ist sicherlich eine andere Art, es zu tun, obwohl ich denke, dass ich das Action-Objekt aus mehreren Gründen lieber in seine eigene First-Class-Entity aufteilen würde. Der größte Grund ist, dass ich glaube, dass es überprüfbar ist. Ob eine Bewegung gültig ist oder nicht, könnte im Aktionsobjekt liegen, anstatt sich darum zu sorgen, dass die Karte jederzeit in einem gültigen Zustand ist. Zugegeben, ich weiß nicht, was beide Ansätze mit sich bringen würden, aber das fühlt sich für mich besser an.

Der andere Grund, den Sie völlig über YAGNI widerlegen können, ist, dass ein Action-Objekt erster Klasse eine Geschichte von Zügen bereitstellen würde. Interessant vielleicht, aber wenn eine Anforderung, ist ein strittiger Punkt.

    
nakajima 02.01.2009 00:55
quelle
1

Einer der Entwickler in planet.jabber ist an Chesspark , eine Online-Schach-Community. Sie verwenden Jabber / XMPP ausgiebig; Wenn ich mich nicht irre, sind dies seine Beiträge zum Thema .

XMPP ist ein Instant-Messaging-Protokoll, das grob auf einem kleinen XML-Nachrichtenaustausch basiert. Es gibt Bibliotheken für die meisten Sprachen, einschließlich Javascript. Ich bin mir nicht sicher, ob es zu deinem Problem passt.

    
alex 02.01.2009 18:59
quelle
1

Bei einem einfachen Spiel wie Schach geht es eigentlich nur darum, den Medientyp zu definieren.

Hier ist ein Beispiel für einen wahrscheinlich vereinfachten Mediatyp, um ein Schachspiel zu modellieren.

Ich überspringe die Verwaltung mehrerer Spiele, die möglicherweise auf demselben Server laufen, und modelliere ein bereits laufendes Spiel.

Der erste Schritt besteht normalerweise darin, einen Index für die Anwendung zu definieren.

index

Der Einstiegspunkt für das Spiel. Holen Sie dies, um Informationen über das Spiel zu entdecken.

Die Payload könnte etwa so aussehen:

%Vor%

move

Senden Sie eine JSON-Payload an Links, die mit einem rel von move gekennzeichnet sind, um ein Stück zu verschieben. Die folgenden Felder müssen enthalten sein:

  • location: Der URI des zu verschiebenden Speicherplatzes

Erfolgreiche Antworten haben einen Statuscode von 200 und enthalten eine Entität, die genauso wie die index Nutzlast mit dem aktualisierten Status des Spiels ist.

400, wenn der Benutzer sein Stück dort nicht bewegen darf oder wenn er nicht an der Reihe ist.

player

ERHALTE eine Beschreibung eines Spielers.

Die folgenden Felder MÜSSEN in der Antwort enthalten sein:

  • Benutzername: Benutzername des Players
  • href: URI identifiziert den Spieler dieses Spiels.

piece

Pieces sind in die index -Nutzlast eingebettet, können aber selbst existieren. Jedes piece MUSS die folgenden Felder haben:

  • type: Ein URI, der den Typ des Stücks angibt. Z.B. Bischof, Turm, König. Das Erhalten dieses URI kann Informationen darüber liefern, wie dieses Stück im Schachspiel funktioniert.
  • href: Ein URI, der das tatsächliche Stück auf diesem Board identifiziert. GET-Anfragen an diesen URI KÖNNEN Informationen zu diesem bestimmten Teil enthalten.

Jedes Stück muss einen move link haben.

Eine alternative Designentscheidung, die ich hier hätte treffen können, war, für jeden gültigen Zug eine individuelle Verbindung bereitzustellen. Es mag gute Gründe dafür geben, aber ich wollte zeigen, dass es nicht erforderlich ist. Es gibt wahrscheinlich eine Handvoll anderer Ressourcen, die Sie verwenden möchten, um Dinge zu behandeln, die dem Kunden helfen, festzustellen, wer an der Reihe ist und was nicht.

Für kompliziertere Spiele, wie Civilization, RTSs, FPSs oder MMOGs und was nicht, ist das vielleicht nicht so praktisch IMO.

    
Nick Robinson 25.03.2017 19:26
quelle

Tags und Links