Xbox サービスの呼び出しのベスト プラクティス
Xbox サービスは、Xbox Services API (XSAPI) を使用するか、REST エンドポイントを直接呼び出すかの、主に 2 つの方法で呼び出せます。 コードでどのように Xbox サービスを呼び出すかにかかわらず、適切な呼び出しパターンと再試行ロジックを備えることが重要です。
適切な再試行ロジックを記述する方法を理解するには、べき等と非べき等の 2 種類の REST エンドポイントについて知る必要があります。 以下、これらについて説明します。
非べき等エンドポイント
繰り返し呼び出しを行うと思わぬ結果が生じる HTTP メソッドは、非べき等と見なされます。 これは、たとえばクライアントがエンドポイントを呼び出して、ネットワークのタイムアウトが発生した場合に、リソースが更新されたものの、メソッドが成功したことをネットワークが呼び出し元に通知できなかった可能性があるため、メソッドを再試行するのは安全ではないことを意味します。
エラー発生時には、クライアントは再試行するのではなく、まず、呼び出しが成功したかどうかを確認するためのクエリを発行する必要があります。 呼び出しが失敗であった場合にのみ再試行する必要があります。
Xbox Services API に含まれる API の一部は、非べき等エンドポイントの呼び出しとして内部的にマーク付けされています。 これらの API は、非べき等エンドポイントの呼び出し時にエラーが発生した場合、そのエンドポイントの再試行を自動的には行いません。
非べき等エンドポイント API の完全な一覧を以下に示します。
-
XblMatchmakingCreateMatchTicketAsync
-
XblMultiplayerWriteSessionAsync
-
XblMultiplayerWriteSessionByHandleAsync
-
XblMultiplayerSendInvitesAsync
-
XblSocialSubmitReputationFeedbackAsync
- XblSocialSubmitBatchReputationFeedbackAsync
べき等メソッド
一方、べき等 HTTP メソッドは、思わぬ結果をそのままにしません。 これはつまり、こうしたメソッドを再試行しても安全であることを意味します。 Xbox Services API に含まれるべき等メソッドはすべて、一定の条件下で自動的に再試行されます。
上の一覧に非べき等として示されなかったすべての API が、べき等 API です。
再試行ロジックのベスト プラクティス
べき等呼び出しの場合、以下の条件については自動的に再試行してください。
- すべてのネットワーク エラー
- 401: Unauthorized
- 408: RequestTimeout
- 429: Too Many Requests
- 500: InternalError
- 502: BadGateway
- 503: ServiceUnavailable
- 504: GatewayTimeout
UWP 上では、401: Unauthorized は固有の処理が行われます。 この値は Xbox サービス認証トークンの有効期限が切れたことを示すため、Xbox サービス API は、OS を呼び出してトークンを更新してから、1 回の再試行として実行されます。
再試行が実行される場合のベスト プラクティスは、"Retry-After" ヘッダーの時間に到達するまでサービスを呼び出さないことです。 現状では XSAPI にこのベスト プラクティスが実装されています。 いずれかの API でエラーの HTTP ステータス コードや "Retry-After" ヘッダーが返された場合、Retry-After の時間になる前に同じ API を追加呼び出しすると、サービスに到達することなく直ちに元のエラーが返されます。
呼び出しを再試行するときのベスト プラクティスは、ランダムな小さな変動を加えて指数バックオフを実行し、サービスに対する負荷を拡散させることです。 XSAPI は既定の遅延 2 秒で起動し、XblContextSettingsSetHttpRetryDelay を使用して制御されます。 つまり、各再試行では既定で 2 秒、4 秒、または 8 秒などの指数バックオフが実行されます。 再試行を試みる一連のデバイス間で負荷をさらに分散させるため、今回と次回のバックオフ値から生じる遅延には、応答時間に基づいた変動が生じます。
呼び出しの再試行に費やす時間はタイトル側で制御する必要があります。 XSAPI を使用する場合、開発者は XblContextSettingsSetHttpTimeoutWindow 関数を使用してこれを直接制御できます。 既定では、これは 20 秒に設定されます。 これを 0 秒に設定すると、事実上、再試行ロジックがオフになります。
内部の HTTP タイムアウトの動的な調整
XSAPI では、XblContextSettingsGetHttpTimeoutWindow に残っている時間に基づいて、内部 HTTP タイムアウトを動的に調整します。
内部の HTTP タイムアウトは、OS が HTTP ネットワーク操作を中止するまでに、その操作に費やす時間を制御します。
XblContextSettingsGetHttpTimeoutWindow に少なくとも 5 秒残っていない限り、呼び出しは再試行されません。これは、呼び出しが完了するのに十分かつ妥当な時間を確保するためです。 このルールは最初の呼び出しには適用されないので、XblContextSettingsSetHttpTimeoutWindow を 0 に設定することは許容され、1 回のみの呼び出しになります。
このロジックにより、API 呼び出しが返されるタイミングについて、XblContextSettingsGetHttpTimeoutWindow がより確定的になるという効果があります。
"Retry-After" ヘッダーが返された場合、"Retry-After" の時間に達するまで再試行は行われません。 "Retry-After" の時間が XblContextSettingsGetHttpTimeoutWindow の後である場合、呼び出しは XblContextSettingsGetHttpTimeoutWindow の最後に返されます。
エラー処理
タイトル デベロッパーは、すべてのサービス呼び出しに対して常に適切なエラー処理を行う必要があり、失敗した応答を適切に処理する必要があります。
Xbox サービスに対する要求がエラー コードを返す結果になることがある次のような状況は、実際に数多くあります。
- ネットワークを利用できない。 たとえば、デバイスが 4G や Wi-Fi の接続を失ったり、ネットワークがダウン状態になった場合。
- サービスに対する負荷が大きすぎる (503)。
- サービスでエラーが発生した (500)。
- サービスに送信された要求が多すぎる (429)。
- 書き込み操作の競合 (412)。 たとえば、マルチプレイヤー セッション内の別のプレイヤーが先に変更を送信した場合。
- ユーザーが禁止されている、またはアクセス許可がない。
- ユーザーがサインアウトした。
これらの状況でゲームが正しく機能するようにするためには、適切なエラー処理が非常に重要です。
エラー処理のベスト プラクティスの詳細については、「エラー処理」を参照してください。
これに関して説明している動画については、Xfest 2015 のビデオの「XSAPI: C++, No Exceptions!」にある Xfest の講演をご覧ください。
最適な呼び出しパターン
バッチ処理要求を使用する
一部のエンドポイントは、バッチ処理、つまり一連の要求を 1 つの呼び出しに集約することをサポートしています。 たとえば、Xbox サービスのプロフィール サービスを使用すると、1 人のユーザーのプロフィールまたはユーザー プロフィールのセットを要求できます。
一連のユーザーのユーザー プロフィールが必要な場合、ユーザー プロフィールごとに 1 回エンドポイントや API を呼び出すのは非常に非効率的です。
それぞれの呼び出しで、多くの認証オーバーヘッドが発生します。 そのため何度も API を呼び出すのではなく、情報が必要なすべてのユーザーを一度に API に渡して、エンドポイントがすべてのユーザー プロフィールを同時に処理し、単一の応答を返すことができるようにします。
ポーリングの代わりにリアルタイム アクティビティ (RTA) サービスを使用する
ベスト プラクティスは、定期的にポーリングする代わりに、リアルタイム アクティビティ (RTA) サービスを使用することです。 リアルタイム アクティビティ サービスは、サービスで対象リソースに変更があったときに、クライアントに通知を送信する WebSocket を公開します。
RTA サービスは、プレゼンスの変更、統計情報の変更、マルチプレイヤー セッション ドキュメントの変更、およびソーシャル関係の変更についての通知を提供します。
クライアントがどのような情報を必要としているかを認識させるために、クライアントが最初に、WebSocket を介してアイテムにサブスクライブする必要があります。 これにより、アイテムの変更があると適切に通知されるため、変更の検出のためにサービスにポーリングする必要がなくなります。
XSAPI は RTA サービスを、クライアントが使用できるサブスクライブ API のセットとして公開しています。
これらの API それぞれに、アイテムの変更時に呼び出されるコールバック関数を引数に取る、対応する *ChangedHandler
API があります。
- XblPresenceSubscribeToDevicePresenceChange
- XblPresenceSubscribeToTitlePresenceChange
- XblUserStatisticsSubscribeToStatisticChange
- XblSocialSubscribeToSocialRelationshipChange
XSAPI クライアント側マネージャーを使用する
XSAPI には、キャッシュおよび特定シナリオの手間がかかる処理をすべて実行するステート マシンとして機能するマネージャーのセットが用意されています。
Social Manager
Social Manager は、フレンド リストとプロフィールに関連する手間がかかる処理をすべて実行します。 Social Manager は、RTA サービスを使用して、フレンド リスト、フレンドのプロフィールおよびプレゼンス データを最新の状態に保ちます。
Social Manager は、ゲーム エンジンから非常に利用しやすい同期 API を公開しています。 Social Manager がサービスから得た最新情報のメモリ内キャッシュを保持しているため、ゲームは Social Manager API を頻繁に呼び出せます。
「Social Manager」を参照してください。
Multiplayer Manager
Multiplayer Manager は、従来のマルチプレイヤー ゲーム用に簡単に使えるソリューションで、マルチプレイヤー セッションを管理できます。 Multiplayer Manager API には、プレイヤーのロスターとセッション管理が含まれていて、ゲームへの招待、途中参加、マッチメイキングの処理、および既存のネットワーク ソリューションへの接続も可能です。 このマネージャーは、従来のマルチプレイヤー フローの実装に関連する手間がかかる処理をすべて実行します。
「Multiplayer Manager」を参照してください。
スロットリング (きめ細かなレート制限)
Xbox サービスには、単一デバイスがサービスに極端な負荷をかけることがないように、スロットリングが導入されています。 重要なのは、タイトルにいつスロットリングが適用されるかを知ることです。
タイトルがスロットリングされたかどうかを判断するには、次のいずれかの方法を使用します。
- HTTP ステータス コード 429 を監視する
- デバッグ アサートを使用する
- Xbox サービス Trace Analyzer ツールを使用する
以下、これらの方法について説明します。
HTTP ステータス コード 429 を監視する
Fiddler を使用して、HTTP ステータス コード 429 が返されたかどうかを監視できます。 JSON 応答に、エンドポイントがどのようにスロットリングされたかに関する詳細が含められます。
次に例を示します。
{
"version":1,
"currentRequests":13,
"maxRequests":10,
"periodInSeconds":120,
"limitType":"Rate"
}
XSAPI を使用している場合、API は HTTP_E_STATUS_429_TOO_MANY_REQUESTS エラーを返し、API 調整についての詳細を示すエラー メッセージを設定します。
デバッグ アサートを使用する
XSAPI の使用時には、デベロッパー サンドボックス内でタイトルのデバッグ ビルドを使用しているときに呼び出しがスロットリングされると、スロットリングが発生したことを直ちにデベロッパーに知らせるため、アサートが発生します。 これは、コードが正しく記述されていないために 429 スロットリング エラーを意図せず見逃すということがないようにするためです。 問題のコードを修正せずにこれらのアサートを無効にして作業を続けたい場合は、XblDisableAssertsForXboxLiveThrottlingInDevSandboxes API を使用します。
XblDisableAssertsForXboxLiveThrottlingInDevSandboxes(
XblConfigSetting::ThisCodeNeedsToBeChanged
);
ただし、この API によってタイトルのスロットリングが回避されるわけではないことに注意してください。 タイトルは、変わらずスロットリングされます。 この API は、開発者サンドボックス内でデバッグ ビルドを使用するときにアサートを無効にするだけです。
Xbox サービス Trace Analyzer ツールを使用する
タイトルがスロットリングされたかどうかを判断するもう 1 つのオプションは、Xbox サービス呼び出しのトレースを記録してから、Xbox サービス Trace Analyzer ツールを使用して、そのトレースを分析することです。
トレースを記録するには、Fiddler を使用して .SAZ ファイルを記録するか、XSAPI の組み込みトレース ログを使用します。 XSAPI でトレースをオンにする方法の詳細については、Xbox の記事「Xbox サービス Trace Analyzer (XblTraceAnalyzer.exe)」を参照してください。 トレースを用意すると、スロットリングされた呼び出しの検出時に Xbox サービス Trace Analyzer ツールが警告を発します。
Xbox サービスは稼働していますか?
Xbox サービスは、プロフィール、フレンドとプレゼンス、統計情報、ランキング、実績、マルチプレイヤー、マッチメイキングなどの Xbox サービスの機能を公開するマイクロサービスの集合体です。 Xbox サービスが稼働中かどうかを決める単一のサーバーやエンドポイントは存在しません。 1 台のサーバーがダウンした場合でも、Xbox サービスの残りのマイクロサービスは、その大部分が独立していて、動作可能です。
1 つのサービスで一時的な停止が発生している場合、そのサービスの呼び出しがゲームにとってミッション クリティカルであるかどうかを知ることが重要です。 ネットワークやサービスの問題が断続的に発生しているときには、適切なエクスペリエンスを提供するようにしてください。 たとえば、プレゼンス サービスがエラーを返している場合、その呼び出しはおそらくゲームにとってミッション クリティカルではありません。 そのためユーザーには、Xbox ネットワーク (Xbox Live とも呼ばれます) がダウンしていることを報告するのではなく、最後の既知のプレゼンス情報を報告するだけにします。
Xbox サービスは、"結果整合性" という一貫性モデルにも従っています。 これは、新しい更新が行われない場合、最終的には、そのリソースに対するすべての要求で、最後に更新された値が報告されることを意味します。 これはつまり、データの伝播中に情報が古いままである、短い期間があることを意味しています。