ターンベースのゲームサーバーにはどのRESTful APIを使用しますか?

StackOverflow https://stackoverflow.com/questions/405588

  •  03-07-2019
  •  | 
  •  

質問

ターンベースのゲームサーバーをRESTful APIとしてどのようにモデル化しますか?たとえば、同じAPIの別のクライアントに対してチェスのゲームをプレイできるチェスサーバー。他のクライアントとゲームをリクエストおよびネゴシエートする方法、およびゲームの個々の動きをプレイする方法が必要になります。

これはREST(RESTful)APIの良い候補ですか?または、これを別の方法でモデル化する必要がありますか?

役に立ちましたか?

解決

モデル化しようとしているリソースは何ですか?あなた、あなたの対戦相手、特定のゲーム(セッション、インスタンス)、およびゲームボードの状態の4つがあるようです。そのため、次のようなもので始まります

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

InfoQ の優れた紹介/概要があります。

>

他のヒント

次のようなことを考えています:

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

基本的なリソースに関する限り。 「他のプレイヤーはまだ動いていますか?」の処理方法がわかりません。しかし、アイデア。私は、移動が再生されるまでGETリクエストをブロックすることを考えてきました。私のクライアントは私の移動の座標をPUTします

/game/13/move/1

そしてGETします

/game/13/move/2

サーバーはすぐに応答しませんが、他のプレーヤーが移動するまで接続を開いたままにします(つまり、その場所にPUTします)。これは中島が「コメット風」と呼んでいるものですか?

チャーリー、「トークン」の意味がよくわかりません。誰の番ですか?これは、ポーリングや接続のブロックを必要とせずに同じ問題を解決しますか?

プレーヤーIDの場合、URLの一部でリソースとしてモデル化するのは理にかなっていますか?私は単純にHTTPユーザー認証(ユーザー/パスがすべてのリクエストの一部として送信される)を使用することを計画していました。認証せずにほとんどのリソースを取得することはできますが、たとえば、

PUT /game/13/move/2

そのゲームの正しいクレデンシャルを持っていない場合、許可拒否エラーが表示されます。

OK、RESTの基本的な考え方は、状態を転送するということです。 「セッション状態」をほとんどまたはまったく持たない場合サーバー上。そのため、セッション状態とキープアライブを使用したくないでしょう。これがCometの機能です。しかし、メールによるゲームの例について考えてみましょう。あなたは両方ともボードのコピーを持っており、動きを交換します。郵便局はこのゲームについて知りません。

今、私はそれについて考えると、これが私の心の中で成長していることを認めます-実際、私はこの質問に基づいて記事を書くかもしれません-しかし、いくつかの物語として、ここにアイデアがあります:

  1. チェスのゲームをプレイしたい 行なので、既知のURIに移動して 取得します。ページを取り戻す 誰が待っているかを示す ゲームを開始します。
  2. あなたは待っている人の一人を選びます 再生するには、適切なをクリックします リンク。新しいディスプレイが表示されます(ajax あなたが望むならここで魔法) ボードのセットアップ。あなたの一人は白です 白が最初に移動します。
  3. 移動する権利のある人は入る 移動、コミット(テイクなど) ゲームでピースから手を離します。) ボードの更新と 他のプレイヤーに移動します。

サーバーの状態に関しては何も必要ありません---ランク付けなどのために、動きなどを追跡することでこれを拡張したい場合があります-そして、誰が動く権利を持っているかという質問を計算できます完全にボードページから:あなたが権利を持っている場合、あなたは動きを入力するためのフォームを持っています。フォームの返信を送信すると、応答は移動を入力するスロットのないページを返します。

「トークン」によって私は、その1ビットの状態「私の動き」/「あなたの動き」の任意の表現を意味します。

必要なリソースがあるかのように見えます

  • 「ゲームを見つける」ホームページ
  • 統計情報を追跡している場合のユーザーページ など
  • すべてのアクティブなゲームの一意のURI。

ありがとう、チャーリー。スキームでの相手の動きをどのように通知するかはまだわかりません。もちろん、誰が移動する権利があるかという質問は、ボードリソースから、または移動する順番を明示的に示す別のリソースを使用して、簡単に計算できます。しかし、クライアントはこのリソースが変更されたことをどのようにして知るのでしょうか?何かが変更されたことに気付くまで、前の状態を記憶して、単に継続的にポーリングする必要がありますか?郵便局モデルでは、郵便局は「プッシュ」します。クライアント(メールボックス)へのメッセージ。これはHTTPでは不可能です。

これはより一般的な質問の一部だと思います:変更や修正を監視したいRESTリソースがある場合、それを行う最善の方法は何ですか?そして、クライアントにとってこれを簡単にするためにサーバーができることはありますか?

それ自体が興味深いと思うので、これを別の質問として実際に投稿すると思います。

追加して編集:何はRESTリソースの変更を監視するRESTfulな方法ですか?

RESTはそのようなアプリケーションには適していないと思います。必要な変換と操作(移動、移動履歴の表示、元に戻す、提案の取得、ターン通知)は、RESTのリソースの概念にきちんとマッピングされません。 (ScrabbleやMonopolyなどのより複雑なターンベースのゲーム用のRESTful APIがどのように見えるかを考慮すると、困難はおそらくより明白になります。)

賢明なREST APIは、おそらくポータブルゲーム表記を前後に。

RESTでモデルできると思います。 = "em://en.wikipedia.org/wiki/Comet_(programming)" rel = "nofollow noreferrer">が必要になるため、実装はより困難になります。彗星)-解決策またはあなたはAJAXを介して比較的短い間隔でサーバーをポーリングする必要があります。

RESTfulインターフェイスを公開する方法については、座標、それらの座標を占有できるピース、およびそれらの座標を変更するアクションを備えたプレイボードが必要だと思います。

プレイヤーが移動すると、新しいアクションが作成されます。許可されていることを確認した後、ゲームのステータスを更新し、UIの更新に必要な応答をレンダリングします。

だからそれは基本的に私がそれをモデル化する方法です。実装側は、ここでより大きな難しさを考慮するものです。

私はそれがすべて複雑ではないと思います、中島。ボードの位置、動き、そして次の動きを持っている人のトークンとともに、JSONなどでデータを渡します。メールで遊ぶのとまったく同じです。

まずはゲームに行き、パートナーを探すことから始めます。

/game/

待っている人のリストが表示されます。入場時に、誰も待っていない場合は、ゲームIDを取得します。それ以外の場合は、待っている人を選んで、その人が持っているゲームIDを取得します。

/game/gameID

はボードを表示します。白を演じる人の決定をセットアップするために何かが必要です。これは演習として残しておきます。 GET操作はボードを提供するため、POSTは移動を送信します。移動できない場合はエラーが発生します。次のGETで結果を見つけます。

地獄、このモデルではゲーマーIDは使用していませんが、キビツァーとしてゲームに忍び込むことはできないので良いかもしれません。

あなたの考えは、アクションをファーストクラスのオブジェクトにする代わりに、各動きはゲーム自体の更新として扱われるということですか?確かにそれは別の方法ですが、いくつかの理由でアクションオブジェクトを独自のファーストクラスエンティティに分割したいと思います。最大の理由は、よりテストしやすいと思うからです。移動が有効であるかどうかは、常にボードが有効な状態にあることを心配する必要なく、アクションオブジェクトに存在します。確かに、どちらのアプローチが何を伴うかはわかりませんが、これは私にとっては気分が良いです。

YAGNIで完全に反論できるもう1つの理由は、ファーストクラスアクションオブジェクトが移動の履歴を提供することです。興味深いかもしれませんが、要件でない限り、重要なポイントです。

planet.jabber の開発者の1人がチェスパーク、オンラインチェスコミュニティ。彼らはJabber / XMPPを広範囲に使用しています。間違っていない場合は、これらのテーマに関する投稿です。

XMPPは、インスタントメッセージングプロトコルであり、大部分は小さなXMLメッセージ交換に基づいています。 Javascriptを含む ほとんどの言語のライブラリがあります。しかし、それがあなたの問題に合うかどうかはわかりません。

チェスのような単純なゲームの場合、実際にはメディアタイプを定義するだけです。

チェスのゲームをモデル化するために、おそらく過度に単純化されたメディアタイプの例です。

同じサーバーで実行されている可能性のある複数のゲームの管理をスキップし、既に実行中のゲームをモデル化します。

最初のステップは通常、アプリケーションへのインデックスを定義することです。

index

ゲームのエントリポイント。これを取得して、ゲームに関する情報を見つけてください。

ペイロードは次のようになります。

{
    "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/..." },
                    ...
                ]
            }
        },

        ...
    ]
}

移動

JSONペイロードを move rel でマークされたリンクに貼り付けて、ピースを移動します。次のフィールドを含める必要があります。

  • location:移動先のスペースのURI

成功した応答のステータスコードは200で、更新されたゲームの状態を持つ index ペイロードと同じエンティティが含まれます。

ユーザーが作品をそこに移動することが許可されていない場合、または自分の番ではない場合。

player

プレーヤーの説明を取得します。

応答には次のフィールドが必要です:

  • username:プレーヤーのユーザー名
  • href:このゲームのプレイヤーを識別するURI。

piece

部分は index ペイロードに埋め込まれますが、それ自体で存在する場合があります。各 piece には次のフィールドが必要です:

  • type:ピースのタイプを識別するURI。例えば。ビショップ、ルーク、キング。このURIを取得すると、チェスのゲーム内でこのピースがどのように機能するかに関する情報が提供される場合があります。
  • href:このボード上の実際のピースを識別するURI。このURIへのGETリクエストは、この特定の部分に関する情報を提供する場合があります。

各ピースには move リンクが必要です。


ここで行うことができた代替設計の決定は、有効な移動ごとに個別のリンクを提供することでした。それをする正当な理由があるかもしれませんが、私はそれが必須ではないことを示したかったです。おそらく、クライアントが誰の番で、何が番であるかを判断するのを助けるようなことを処理するために含めたい他のリソースがいくつかあります。

Civilization、RTS、FPS、またはMMOGなどのより複雑なゲームの場合、そうではない場合、これはそれほど実用的なIMOではない可能性があります。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top