ネットワーク初期化
この記事では、Microsoft Game Development Kit (GDK) タイトルにおいてネットワークの接続状態や初期化情報を取得する方法について解説します。GDK タイトルは、コア OS コンポーネントやネットワーク サービスが起動する前に起動されることがよくあります。そのため、タイトル起動直後にWinSock、WinHTTP、BCrypt、WinCrypt、schannel、IPHLPAPI など、ほとんどのネットワークおよびセキュリティ API を呼び出そうとすると、不定な動作を招く可能性があります。この動作には、予期しない失敗、初期化されていない戻り値、任意のパケット ロス、メモリ破損やクラッシュなどが含まれます。
このような不定な動作を回避するため、Microsoft Game Development Kit (GDK) タイトルでは XNetworkingGetConnectivityHint と XNetworkingRegisterConnectivityHintChanged 関数を使用してください。特に、XNetworkingConnectivityHint::networkInitialized フィールドはネットワークが初期化済みかどうかを示します。タイトルは、ネットワークおよびセキュリティ API を呼び出す前に、networkInitialized フィールドが true になるのを待つ必要があります。
多くのミドルウェア ライブラリも内部でネットワーク API やセキュリティ API を使用します。ネットワーク以外のミドルウェアであっても、テレメトリやデバッグ用にネットワーク スタックを使用する場合があります。各ケースでどう対応すべきかは、ミドルウェア提供元に確認してください。ミドルウェア自身がネットワーク初期化を待機しない場合、ネットワークが初期化されるまでミドルウェアのロードを遅延させる必要があります。Microsoft Game Development Kit (GDK) 内のいくつかのライブラリ、たとえば XSAPI や Azure PlayFab Party は、使用前にネットワークの初期化を待機する必要があります。
HTTP スタックのシーケンス
このドキュメント セット内で、ネットワーク初期化を自動的に管理する HTTP ライブラリはxCurl と libHttpClient だけです。タイトルがそれ以外の HTTP スタックを使用する場合は、起動シーケンスを明示的に記述してください。安全なパターンは次のとおりです。
- 現在の接続ヒントを問い合わせるか、接続変更のリスナーを登録する。
XNetworkingConnectivityHint::networkInitializedがtrueになるまで待機する。WinSockおよびその他のネットワーク依存関係を初期化する。- 証明書の状態にアクセスし、信頼設定を構成する。
- HTTP スタックを作成し、リクエストの発行を開始する。
WinSock、証明書の状態、または HTTP の状態を早期に立ち上げると、目に見えるエラーが根本原因よりも遅れて発生することが多いため、原因の特定が困難になります。
次の例は、タイトルが所有する HTTP スタックの起動シーケンスの最初の数ステップを示しています。この例では、WinSock を起動する直前に XNetworkingConnectivityHint を直接問い合わせています。
サスペンドとレジューム
さらに、タイトルのサスペンド/レジューム サイクルによってnetworkInitialized フィールドは false にリセットされます。サスペンド時には、タイトルはネットワークおよびセキュリティ コンポーネントのすべてのハンドルをクリーンアップし、すべてのネットワーク操作を停止する必要があります。サスペンド時における各ネットワーク API の要件については、各 API の概要ページを参照してください。レジューム時には、タイトルは再び networkInitialized フィールドが true になるのを待ってから、接続の再確立やネットワーク/セキュリティ API の使用を試みてください。レジューム時のネットワーク初期化パスは、初回タイトル起動時のパスと同じにすることを推奨します。つまり、レジュームでもタイトル起動でも、ネットワークが初期化されるまで待ってからネットワーク コードを開始します。GameChat2 や Azure PlayFab Party のようにサスペンド/レジュームを認識しないミドルウェア ライブラリは、サスペンド時にクリーンアップし、レジューム後にネットワークが初期化されるのを待ってから再初期化する必要があります。
xCurl 以外のすべての HTTP スタックは、明示的なライフサイクル管理を必要とすると考えてください。サスペンドまたはシャットダウン時には、新しいリクエストのキューイングを停止し、実行中の処理をキャンセルまたは完了させます。サスペンド中に保持すべきでないリクエスト ハンドル、セッション、ソケットを破棄します。
レジューム時には、ネットワークの立ち上げを新規の初期化パスとして扱ってください。HTTP 状態を再作成したり、リスナーを再登録したりする前に、再度 networkInitialized を待機します。キャンセル可能で非ブロッキングな作業に基づく設計は、長時間ブロックする呼び出しよりもサスペンド時にきれいに巻き戻せます。
ネットワーク初期化のテスト
ネットワーク初期化には、レジューム時とタイトル起動時のいずれでも通常数秒かかり、コンソールの種類やユーザーのネットワーク環境によって変動します。開発中はネットワーク初期化がほぼ瞬時に完了するため、タイトルの各部分がネットワーク初期化を適切に待機していない問題が隠れてしまうことがあります。ネットワーク初期化シナリオをテストするには、xbconfig NetworkInitDelayInSeconds=30 を使用してネットワーク初期化プロセスに任意の遅延を追加します。この設定を使用する場合は、テストごとに xbapp terminate /full を使ってタイトルを完全に再起動してください。テストが完了したら、NetworkInitDelayInSeconds を 0 に戻します。
独自のネットワーク状態を作成する HTTP スタックの場合は、少なくとも次のシナリオをテスト対象に含めてください。
- コールド ブート
- リクエストがアクティブな状態でのサスペンド
- クリーン サスペンド後のレジューム
- Quick Resume または同等の復元フロー
- サスペンドおよびレジュームの境界周辺でのネットワーク切断
ネットワーク初期化のコード例
次のコード例は、リアルタイム安全な方法でネットワークが初期化されているかどうかをポーリングする方法を示しています。ネットワーク情報
Microsoft Game Development Kit (GDK) タイトルにおけるネットワーク情報は、XNetworkingGetConnectivityHint API で取得できます。 XNetworkingGetConnectivityHint API は、デバイス全体のネットワーク接続レベル、データ制限、有線と無線の接続タイプ、およびネットワーク初期化状態などの情報を返します。これは現在の情報をただちに返す、リアルタイム安全な API です。変更の受信には、XNetworkingRegisterConnectivityHintChanged および XNetworkingUnregisterConnectivityHintChanged 関数を使用します。 次のコード例は、XNetworkingGetConnectivityHint 関数を使用して現在のネットワーク状態に関する情報を照会する方法を示しています。ネットワーク接続のベスト プラクティス
返される XNetworkingConnectivityHint 構造体のうち、XNetworkingConnectivityHint::networkInitialized 以外のフィールドはヒントです。これらは、デバイスが観測したネットワーク トラフィックのヒューリスティックに基づく、ネットワーク現在の状態のベスト エフォート推測です。
XNetworkingConnectivityLevelHint の状態は、タイトルの接続ロジックを単純化するための一般的なネットワーク レベルの近似を表します。タイトルは、ネットワーク環境が数分間変化していない安定状態でネットワーク メディアの切断や一般的な接続不足を反映するものとして XNetworkingConnectivityLevelHint::None を扱うことができます。それ以外の状態は、タイトル固有のエンドポイントへの接続性を表すものではありません。
そのため、ネットワーク初期化を待った後は、XNetworkingConnectivityHint::connectivityLevelHint フィールドの状態にかかわらず、WinSock や WinHTTP を使ってエンドポイントへの接続確立を試みることを推奨します。それらの API が後で失敗した場合は、UI 表示や診断報告用に XNetworkingGetConnectivityHint API を使用してください。そして、ネットワーク接続レベルが変化するのを待ってから再試行します。
高度なネットワーク情報の取得
ほとんどの Microsoft Game Development Kit (GDK) タイトルでは、ネットワークの状態や IP アドレスなどの基本情報の取得には、XNetworkingGetConnectivityHint API とWinSock API を組み合わせて使用してください。さらに詳しい情報が必要な場合は、GDK で低レベルの IP Helper API が利用可能です。
一般的に、Microsoft Game Development Kit (GDK) での IP Helper API の扱い方は、Win32 プログラムでの扱い方と同じです。
-
ソース ファイルで、
#include <winsock2.h>の後に#include <iphlpapi.h>を記述します。 -
Ws2_32.libとIphlpapi.libを直接リンクする代わりに、XGamePlatform.libにリンクします。
WINAPI\_PARTITION\_GAMES API ファミリの API のみが動作します。
XBOX コンソールでは、基盤となるプラットフォーム抽象化のために、IP Helper API を使用しても正確でない情報があります。これには、次のような例が含まれますが、これらに限りません。
- MAC アドレスは常に
AA-AA-AA-AA-AA-AAです。 - すべてのインターフェイスは、基盤となるネットワーク接続タイプに関係なく、常に有線インターフェイスとして報告されます。実際のインターフェイス タイプは XNetworkingGetConnectivityHint からのみ取得できます。
