Che RESTful API che si utilizza per un server di gioco a turni?

voti
8

Come si modellare un server di gioco a turni come un'API RESTful? Ad esempio, un server di scacchi, dove si potrebbe giocare una partita a scacchi contro un altro cliente della stessa API. Si avrebbe bisogno di un certo modo di richiedere e negoziare un gioco con l'altro cliente, e in qualche modo di giocare i singoli movimenti del gioco.

È questo un buon candidato per un API REST (RESTful)? O questo dovrebbe essere modellato un modo diverso?

È pubblicato 01/01/2009 alle 21:34
fonte dall'utente
In altre lingue...                            


10 risposte

voti
1

Penso che si potrebbe modellare esso restfully. L'implementazione sarà più difficile, perché ci si sia bisogno di una cometa ) Soluzione -esque o che avrebbe dovuto essere il polling del server in un intervallo relativamente breve tramite la tecnologia AJAX.

In termini di come ci si espone un'interfaccia RESTful, direi che avete bisogno di un tavolo da gioco con le coordinate, pezzi che possono occupare quelle coordinate, e le azioni che alterano quelle coordinate.

Quando un giocatore fa una mossa, si verrebbe a creare una nuova azione. Dopo la convalida per assicurarsi che sia consentito, devi aggiornare lo stato del gioco, quindi il rendering qualunque sia la risposta che è necessario per aggiornare l'interfaccia utente.

Ecco, questo è fondamentalmente come avrei modello IT. Il lato implementazione è quello che mi piacerebbe prendere in considerazione la difficoltà più grande qui però.

Risposto il 01/01/2009 a 21:44
fonte dall'utente

voti
2

Quali sono le risorse che si sta cercando di modellare? Mi sembra di avere quattro: Tu, il tuo avversario, il particolare gioco (sessione, esempio) e lo stato di gioco. Quindi sarebbe iniziare con qualcosa di simile

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

abbiamo una buona introduzione / panoramica InfoQ .

Risposto il 01/01/2009 a 21:46
fonte dall'utente

voti
1

Io non credo che sia tutto ciò che complciated, Nakajima. Si potrebbe passare i dati, dire in JSON, per la posizione di bordo, per gli spostamenti, e con un token per chi ha la prossima mossa. Sarebbe esattamente come giocare per posta.

Si inizia andando al gioco e alla ricerca di un partner, in modo da

/game/

ti dà un elenco di persone in attesa. quando si arriva in, se non c'è nessuno in attesa di ottenere un ID di gioco; altrimenti si sceglie qualcuno in attesa e ottenere l'ID del gioco che hanno.

/game/gameID

vi mostra la scheda. Hai bisogno di qualcosa di impostare la decisione che interpreta bianco, lascio che come esercizio. L'operazione GET ti dà il consiglio, quindi un POST invia una mossa; se non si ha la mossa si ottiene un errore. A trovare il risultato per il prossimo GET.

L'inferno, in questo modello non sono nemmeno utilizzando l'ID giocatore, anche se potrebbe essere un buon modo che nessuno possa intrufolarsi nel gioco come un kibitzer.

Risposto il 01/01/2009 a 22:01
fonte dall'utente

voti
1

Così il vostro pensiero è che invece di fare le azioni di un oggetto di prima classe, ogni mossa sarebbe stata trattata come un aggiornamento del gioco stesso? E 'certamente un modo diverso per farlo, anche se penso che preferirei per dividere l'oggetto azione fuori nella sua propria entità di prima classe per un paio di ragioni. La ragione principale è che credo che sia più verificabili. O se non una mossa è valida potrebbe vivere nell'oggetto azione, invece di aver bisogno di preoccuparsi per la scheda di essere in uno stato valido in ogni momento. Certo, io non so cosa sia l'approccio comporterebbe, ma questo si sente meglio a me.

L'altro motivo, che si può assolutamente rifiutare via YAGNI, è che un oggetto prima class action fornirebbe una storia di mosse. Interessante, forse, ma a meno che un obbligo, è un punto controverso.

Risposto il 01/01/2009 a 23:55
fonte dall'utente

voti
4

Sto pensando qualcosa del tipo:

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

Per quanto riguarda le risorse di base sono interessati. Non sono sicuro di come gestire la "ha l'altro giocatore si trasferisce ancora?" idea, però. Ho pensato di avere semplicemente il blocco di richiesta GET fino a quando il movimento è giocato - vale a dire il mio cliente avrebbe messo le coordinate della mia mossa a

/game/13/move/1

e poi otterrebbe

/game/13/move/2

Il server non rispondere immediatamente, ma mantenere aperta la connessione fino a quando il giocatore si trasferisce (cioè PUT in quella posizione). È questo ciò che Nakajima si riferisce a come "la cometa-esque"?

Charlie, io non sono molto sicuro di cosa si intende per il "token" di cui è il turno - fa questo a risolvere lo stesso problema senza la necessità di polling o una connessione di blocco?

Per gli ID dei giocatori, ha senso per modellare quelli come una risorsa in una parte del URL? Avevo intenzione di utilizzare semplicemente autenticazione utente HTTP (in cui l'utente / passaggio viene inviato come parte di ogni richiesta). Si potrebbe ancora ottenere la maggior parte delle risorse senza autenticazione, ma se si è tentato di, diciamo,

PUT /game/13/move/2

si darebbe un errore di negato il permesso se non si dispone delle credenziali corrette per quel gioco.

Risposto il 02/01/2009 a 00:09
fonte dall'utente

voti
4

Va bene, l'idea di base di REST è che si sta trasferendo lo stato; si desidera avere poca o nessuna "stato sessione" sul server. Quindi non si vuole utilizzare lo stato di sessione e di un keepalive, che è ciò che fa la cometa. Ma pensare l'esempio di un gioco play-by-mail: Entrambi avete una copia della scheda, e si scambiano mosse. L'ufficio postale non conosce il gioco.

Ora, devo ammettere questo sta crescendo nella mia mente come penso a questo proposito - in realtà, posso scrivere un articolo sulla base di questa domanda - ma ecco l'idea, come alcune storie:

  1. Si vuole giocare una partita a scacchi on line, in modo da andare ad un noto URI per ottenere uno. Si ottiene di nuovo una mostra pagina che, se qualcuno, è in attesa di iniziare una partita.
  2. È possibile scegliere una delle persone in attesa di giocare, e fare clic sul collegamento appropriato. Si ottiene un nuovo display (magia ajax qui se volete) con la scheda istituito. Uno di voi è bianco, si muove bianchi prima.
  3. Chiunque ha il diritto di circolare entra in una mossa, e si impegna (come prendere la mano dal pezzo in un gioco.) Gli aggiornamenti da tavolo e il diritto di circolare va al giocatore.

Non hai bisogno di qualcosa molto in termini di stato del server --- anche se si potrebbe desiderare di estendere questo tenendo traccia dei movimenti, ecc, diciamo per ranking - e la questione di chi ha il diritto di circolare può essere calcolata interamente dal pagina pensione: se avete il diritto, si dispone di un modulo per l'inserimento di una mossa; quando si invia la forma di ritorno, la risposta restituisce una pagina a voi con nessuno slot per l'inserimento di una mossa.

Con "il token" Volevo solo dire qualche rappresentazione arbitraria di che un bit di stato "Il mio movimento" / "la mossa".

Sembra come se le risorse necessarie sono

  • A "trovare un gioco" home page
  • Una pagina di utente se si sta monitorando le statistiche e come
  • un URI unico per ogni gioco attivo.
Risposto il 02/01/2009 a 01:32
fonte dall'utente

voti
2

Grazie, Charlie. Io non sono ancora chiaro come si ottiene notifica della mossa dell'avversario nel vostro schema. Naturalmente la questione di chi ha il diritto di circolare può essere calcolato semplicemente - sia dalla risorsa bordo, oppure utilizzando una risorsa separata che afferma esplicitamente di turno è quello di spostare. Ma come fa un cliente sa che questa risorsa è cambiato? Ha a polling semplicemente continuamente, ricordando lo stato precedente, fino a quando non si accorge che qualcosa è cambiato? Nel modello Post Office, l'ufficio postale "spinge" un messaggio al client (tua casella di posta), che non è possibile in HTTP.

Suppongo che questo è parte di una questione più generale: se c'è una risorsa REST che voglio per monitorare cambiamenti o modifiche, qual è il modo migliore per farlo? E c'è qualcosa che il server può fare per rendere questo più facile per il cliente?

Penso che in realtà questo post come una questione separata in quanto penso che sia interessante di per sé.

A cura di aggiungere: Che è un modo RESTful di monitorare una risorsa REST per le modifiche?

Risposto il 02/01/2009 a 02:06
fonte dall'utente

voti
1

Uno degli sviluppatori in planet.jabber è coinvolto in Chesspark , una comunità di scacchi on-line. Essi utilizzano Jabber / XMPP ampiamente; se non sbaglio, questi sono i suoi messaggi sul tema .

XMPP è un protocollo di messaggistica istantanea, più o meno sulla base di piccolo scambio di messaggi XML. Ci sono librerie per la maggior parte delle lingue, tra cui Javascript. Io non sono sicuro che si adatta al vostro problema, però.

Risposto il 02/01/2009 a 17:59
fonte dall'utente

voti
2

Non credo che REST è una buona scelta per una tale applicazione. Le trasformazioni e le operazioni che dovete fare (far muovere, vista cronologia di spostamento, annullare, ottenere suggerimenti, girare notifica) non mappare perfettamente al concetto di REST delle risorse. (Le difficoltà sono forse più evidente se si considera come un'API RESTful per più complicati giochi a turni come Scarabeo o Monopoly potrebbe apparire.)

Credo che qualsiasi API REST sensata sarebbe probabilmente finiscono per essere un wrapper qualcosa non RESTful, come ad esempio un protocollo stateful che ha inviato la notazione gioco portatile avanti e indietro.

Risposto il 17/05/2010 a 16:18
fonte dall'utente

voti
1

Per un gioco semplice come gli scacchi, in realtà è solo su come definire il MediaType.

Ecco un esempio di quello che è probabilmente un MediaType sopra semplificata per modellare una partita a scacchi.

Ho intenzione di saltare la gestione di più giochi che possono essere in esecuzione sullo stesso server e solo modellare un gioco già in esecuzione.

Il primo passo è di solito per definire un indice per l'applicazione.

index

Il punto di ingresso per il gioco. Fetch questo per scoprire informazioni sul gioco.

Il carico utile potrebbe essere simile a questo:

{
    "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

POST un carico utile JSON per i collegamenti contrassegnati con un reldi moveper spostare un pezzo. I seguenti campi devono essere inclusi:

  • location: l'URI dello spazio per passare al

Le risposte di successo hanno un codice di stato di 200 e conterranno un soggetto che lo stesso come il indexpayload con lo stato aggiornato della partita.

400 se l'utente non è autorizzato a spostare il suo pezzo lì, o se non è il suo turno.

player

Ottenere una descrizione di un giocatore.

I seguenti campi devono essere nella risposta:

  • Nome utente del giocatore: nome utente
  • href: URI che identifica il giocatore di questo gioco.

piece

I pezzi sono incorporati nel indexpayload, ma può esistere per conto proprio. Ogni piecedeve avere le seguenti campi:

  • tipo: Un URI identifica il tipo di pezzo. EG Alfiere, Torre, King. Ottenendo questo URI possono fornire informazioni su come funziona questo pezzo all'interno del gioco degli scacchi.
  • href: Un URI che identifica la parte reale su questo bordo. GET richieste a questo URI può fornire informazioni su questo particolare pezzo.

Ogni pezzo deve avere un movecollegamento.


Una decisione di progettazione alternativa avrei potuto fare qui era quello di fornire un collegamento individuale per ogni mossa valida. Ci possono essere buone ragioni per farlo, ma volevo dimostrare che non è necessario. Probabilmente ci sono una manciata di altre risorse che si vorrebbe includere per gestire le cose come aiutare il cliente determineranno di turno e quant'altro.

Per i giochi più complicati, come Civilization, RTS, FPS, o MMOG e cosa no, questo potrebbe non essere così pratico IMO.

Risposto il 25/03/2017 a 17:26
fonte dall'utente

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more