Frage

Wie würdet Ihr Modell ein rundenbasiertes Spiel server als RESTful API?Zum Beispiel, ein Schach-server, wo Sie konnten, spielen Sie eine Partie Schach gegen einen anderen client, der die gleiche API.Sie müsste irgendeine Art und Weise zu beantragen und verhandeln ein Spiel mit den anderen client, und in gewisser Weise ist die Wiedergabe der individuellen Züge des Spiels.

Ist dies ein guter Kandidat für einen REST (RESTful) API?Oder sollte dies modelliert werden einen anderen Weg?

War es hilfreich?

Lösung

Was sind die Ressourcen, die Sie zu modellieren sind versuchen? Ich würde scheinen vier zu haben: Sie, Ihre Gegner, das bestimmte Spiel (Session-Instanz) und das Spielbrett Zustand. So würde es wie mit etwas beginnen

/game
/game/gameID/gamer/gamerID
/game/gameID/board

Wir haben ein gutes Intro / Übersicht bekam auf InfoQ .

Andere Tipps

Ich denke, so etwas wie:

/game/<gameID>/move/<moveID>

soweit die grundlegenden Ressourcen betroffen sind. Ich bin mir nicht sicher, wie das zu handhaben „hat der andere Spieler bewegt noch?“ Idee, though. Ich habe einfach gedacht, über die GET-Anforderung Block, bis der Zug gespielt wird - das heißt. mein Mandant würde die Koordinaten von meinem Umzug nach

PUT
/game/13/move/1

und dann würde GET

/game/13/move/2

Der Server würde nicht sofort antworten, aber halten Sie die Verbindung offen, bis der andere Spieler bewegt (das heißt PUT an dieser Stelle). Ist das, was nakajima bezieht sich auf den als „Komet-esque“?

Charlie, ich ist nicht ganz sicher, was Sie von den „Token“ bedeuten für dessen Zug es ist - dies das gleiche Problem für die Abfrage oder eine blockierenden Verbindung, ohne die Notwendigkeit löst

Für Spieler-IDs, macht es Sinn, diejenigen als Ressource in einem Teil der URL zu modellieren? Ich hatte geplant, einfach HTTP-Benutzerauthentifizierung verwenden (wobei der Benutzer / Pass als Teil jeder Anforderung gesendet wird). Sie könnten immer noch die meisten Ressourcen ohne Authentifizierung, aber wenn man versucht, sagen wir,

PUT /game/13/move/2

es werden Sie eine Erlaubnis verweigert Fehler, wenn Sie nicht die richtigen Anmeldeinformationen für das Spiel haben.

Okay, ist die Grundidee, dass Sie den Zustand sind zu übertragen; Sie wenig oder gar keinen „Sitzungsstatus“ auf dem Server haben. Sie würde also nicht den Sitzungszustand und eine Keep-Alive verwenden will, das ist es, was Comet tut. Aber denken Sie am Beispiel eines Play-by-Mail-Spiel: Sie haben beide eine Kopie des Vorstandes, und tauschen Sie bewegt. Die Post nicht weiß, über das Spiel.

Nun, ich gebe zu, dass dies in meinem Kopf wächst, wie ich darüber nachdenke - in der Tat kann ich einen Artikel schreiben über diese Frage basiert - aber hier ist die Idee, da einige Geschichten:

  1. Sie wollen eine Partie Schach spielen Linie, so dass Sie auf einen bekannten URI gehen bekommen ein. Sie erhalten eine Seite zurück zeigt, die, wenn überhaupt jemand wartet ein Spiel zu starten.
  2. Sie wählen eine der Leute, die warten zu spielen, und klicken Sie auf den entsprechenden Verknüpfung. Sie erhalten eine neue Anzeige (Ajax Magie in hier, wenn Sie mit dem wollen) Board eingerichtet. Einer von Ihnen ist weiß, Weiß bewegt sich zuerst.
  3. Wer das Recht hat, sich zu bewegen tritt eine Bewegung, und Commits (wie unter Ihre Hand aus dem Stück in einem Spiel.) Das Board-Updates und das Recht auf Umzug geht an den anderen Spieler.

Sie müssen nichts viel in Bezug auf Serverzustand --- obwohl Sie diese erweitern möchten durch die Verfolgung der Bewegungen usw., sagen für das Ranking - und die Frage, wer das Recht hat, bewegen kann berechnet werden vollständig von der Platine Seite: wenn Sie das Recht haben, haben Sie ein Formular einen Schritt zur Eingabe; Wenn Sie das Formular Rückkehr zurück zu senden, gibt die Antwort, eine Seite zu Ihnen ohne Steckplatz für einen Zug eingeben.

Mit dem „Token“ Ich meine nur einige willkürliche Darstellung dieses ein bisschen Zustand „Mein Umzug“ / „Ihre Bewegung“.

Es scheint, als ob die Ressourcen, die Sie brauchen, sind

  • Eine Homepage "ein Spiel finden"
  • Eine Benutzerseite, wenn Sie Statistiken sind Tracking und so
  • eine eindeutige URI für jedes aktives Spiel.

Danke, Charlie. Ich bin immer noch nicht klar, wie Sie von den gegnerischen Bewegung in Ihrem Schema Benachrichtigung. Natürlich ist die Frage, wer das Recht hat, einfach berechnet werden bewegen können - entweder vom Brett Ressource oder durch eine separate Ressource verwenden, die ausdrücklich darauf hin, der am Zuge ist zu bewegen. Aber woher weiß ein Kunde, dass diese Ressource hat sich geändert? Hat es einfach kontinuierlich abzufragen, den vorherigen Zustand zu erinnern, bis er etwas merkt, hat sich geändert? Im Modell Post Office "schiebt" die Post eine Nachricht an den Client (Mailbox), die in HTTP nicht möglich ist.

Ich nehme an, dies ist Teil einer allgemeineren Frage ist: wenn es eine REST-Ressource, die ich für Änderungen oder Modifikationen, die überwacht werden soll, was ist der beste Weg, dies zu tun? Und gibt es etwas, kann der Server dies einfacher für die Kunden machen tun?

Ich glaube, ich werde dies tatsächlich Post als eine separate Frage, da ich es interessant, selbst zu denken.

Edited hinzufügen: Was ist eine RESTful Weise eine REST-Ressource für Änderungen zu überwachen?

Ich glaube nicht, REST eine gute Wahl für eine solche Anwendung ist. Die Transformationen und Operationen, die Sie tun müssen, (machen bewegen, Ansicht verschieben Geschichte, rückgängig zu machen, einen Vorschlag erhalten, wenden Benachrichtigung) Karte nicht ordentlich zu REST Konzept der Ressourcen. (Die Schwierigkeiten sind vielleicht noch deutlicher, wenn man bedenkt, wie eine RESTful API für kompliziertere Turn-basierte Spiele wie Scrabble oder Monopoly aussehen könnte.)

Ich denke, jeder vernünftige REST-API würde wahrscheinlich ein Wrapper um etwas nicht RESTful, wie eine Stateful-Protokoll am Ende wird die tragbare Spiel Notation hin und her.

Ich denke, man könnte Modell es restfully. Implementieren wird es schwieriger sein, weil Sie entweder eine Komet ) -esque Lösung oder würden Sie Polling den Server in einem relativ kurzen Intervall über AJAX sein.

Im Hinblick darauf, wie Sie eine RESTful-Schnittstelle aussetzen würden, würde ich sagen, dass Sie ein Spielbrett mit den Koordinaten benötigen, Stücke, die diese Koordinaten besetzen können, und Aktionen, die diese Koordinaten ändern.

Wenn ein Spieler einen Zug macht, würde eine neue Aktion erstellt. Nach Validierung es erlaubt, um sicherzustellen, können Sie den Status des Spiels aktualisieren würden, dann machen, was Antwort benötigt wird, um die Benutzeroberfläche zu aktualisieren.

Also das ist im Grunde, wie ich würde es modellieren. Die Umsetzung Seite ist, was ich die größere Schwierigkeit obwohl hier betrachten würde.

Ich glaube nicht, es ist alles, was complciated, Nakajima. Sie würden Daten übergeben, sagen in JSON, für die Vorstandsposition, für die sich bewegt, und mit einem Token für die den nächsten Zug hat. Es wäre genauso wie per Post zu spielen.

Sie beginnen mit dem Spiel zu gehen und suchen einen Partner, so

/game/

gibt Ihnen eine Liste der Leute, die warten. wenn Sie kommen in, wenn niemand da ist, warten Sie ein Spiel ID erhalten; sonst holen Sie jemanden warten und das Spiel ID haben sie bekommen.

/game/gameID

zeigen Sie den Vorstand. Sie brauchen etwas, die Entscheidung zu gründen, die spielt weiß, ich werde das als eine Übung verlassen. Die GET-Operation gibt Ihnen das Brett, so dass ein POST einen Zug sendet; wenn Sie nicht über den Umzug haben erhalten Sie einen Fehler. Sie finden das Ergebnis durch die nächste GET.

Zur Hölle, in diesem Modell bin ich nicht einmal die Spieler-ID, obwohl es so gut sein könnte niemand das Spiel als kibitzer schleicht sich in.

Also Ihr Gedanke ist, dass stattdessen die Aktionen Objekt eine erste Klasse zu machen, jede Bewegung als Update des Spiels behandelt werden würde selbst? Es ist sicherlich eine andere Art und Weise, es zu tun, obwohl ich glaube, ich würde es vorziehen, das Aktionsobjekt aus in seine eigenen ersten Klasse Einheit für ein paar Gründe zu teilen. Der wichtigste Grund dafür ist, dass ich es mehr prüfbar glauben. Unabhängig davon, ob eine Bewegung gilt im Aktionsobjekt leben könnte, statt um über das Brett ist in einem gültigen Zustand jederzeit zu kümmern. Zugegeben, ich weiß nicht, was entweder Ansatz mit sich bringen würde, aber das fühlt sich besser für mich.

Der andere Grund, die Sie über YAGNI völlig widerlegen können, ist, dass ein erstes Klasse Aktionsobjekt eine Geschichte von Bewegungen bieten würde. Interessant vielleicht, aber es sei denn, eine Anforderung, ist ein strittiger Punkt.

Einer der Entwickler in Planeten.jabber beteiligt ist Chesspark, eine online-Schach-community.Sie sind mit Jabber/XMPP ausgiebig;wenn ich mich nicht Irre, diese sind seine Beiträge zum Thema.

XMPP ist ein instant-messaging-Protokoll, grob basierend auf kleine XML-message exchange.Es gibt Bibliotheken für die meisten Sprachen, einschließlich Javascript.Ich bin mir nicht sicher, es wird passen Ihre problem, obwohl.

Für ein einfaches Spiel wie Schach, ist es wirklich nur um den Medientyp zu definieren.

Hier ist ein Beispiel dafür, was wahrscheinlich ein über vereinfachtes media ein Schachspiel zu modellieren.

Ich werde die Verwaltung mehrerer Spiele überspringen, die auf demselben Server ausgeführt werden können und nur ein bereits laufendes Spiel modellieren.

Der erste Schritt ist in der Regel um einen Index zu der Anwendung zu definieren.

index

Der Einstiegspunkt für das Spiel. Fetch diese Informationen über das Spiel zu entdecken.

Die Nutzlast könnte wie folgt aussehen:

{
    "links": {
        "self": "http://my-chess-game.host/games/123",
        "player": "http://my-chess-game.host/players/1",
        "player": "http://my-chess-game.host/players/2",
        "me": "http://my-chess-game.host/players/1",
         ...
    }
    "board": [
        {
           "x": 0,
           "y": 1,
           "piece": null,
           "rel": "space",
           "href": "http://my-chess-game/.../boards/123/0/1/something-random-to-discourage-uri-construction"
        },
        {
           "x": 1,
           "y": 2,
           "rel": "space",
           "href": "...",
           "piece": {
               "player": "http://my-chess-game/.../players/1",
               "type": "http://my-chess-game/pieces/Bishop",
               "rel": "piece",
               "href": "http://my-chess-game/games/123/pieces/player1/Bishop/1",
               "links": [
                    { "rel": "move": "href": "http://my-chess-game/.../boards/123/..." },
                    ...
                ]
            }
        },

        ...
    ]
}

move

Stellen Sie eine JSON Nutzlast auf Links mit einem rel von move markiert ein Stück zu bewegen. Die folgenden Felder müssen enthalten sein:

  • Ort: die URI des Raumes zu bewegen, um

Erfolgreiche Antworten haben einen Statuscode von 200 und eine Einheit, die die gleiche wie die index Nutzlast mit dem aktualisierten Zustand des Spiels enthalten.

400, wenn der Benutzer nicht erlaubt ist, sein Stück dort zu bewegen, oder ob es nicht an der Reihe ist.

player

GET eine Beschreibung eines Spielers.

Die folgenden Felder in der Antwort werden müssen:

  • Benutzername: Benutzername des Spielers
  • href. URI die Spieler dieses Spiels zu identifizieren

piece

Pieces ist in der index Nutzlast eingebettet, sondern kann allein existieren. Jede piece MÜSSEN Sie die folgenden Felder haben:

  • Typ: A URI den Typ des Stückes zu identifizieren. Z.B. Bishop, Rook, König. Geting diese URI bereitstellen können Informationen darüber, wie dieses Stück im Schachspiel funktioniert.
  • href: Ein URI das eigentliche Stück auf diesem Board zu identifizieren. GET-Anfragen zu dieser URI kann Informationen über dieses besondere Stück liefern.

Jedes Stück muss eine move Verbindung hat.


Eine alternative Konstruktion Entscheidung, die ich hier gemacht haben könnte, war eine individuelle Verbindung für jede gültige Bewegung zu sorgen. Es kann gute Gründe, das zu tun, aber ich wollte zeigen, dass es nicht erforderlich ist. Es gibt wahrscheinlich eine Handvoll anderer Ressourcen, die Sie wollen würde gehören Dinge zu handhaben wie der Kunde bestimmen helfen, der am Zug ist und so weiter.

Für kompliziertere Spiele, wie Civilization, RTSs, Egoshooter oder MMOGs und was nicht, diese IMO nicht so praktisch sein kann.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top