> ## Documentation Index
> Fetch the complete documentation index at: https://devdocs.xbox.com/llms.txt
> Use this file to discover all available pages before exploring further.

# ネットワーク初期化状態の検出

> ネットワーク初期化状態の検出

## ネットワーク初期化

この記事では、Microsoft Game Development Kit (GDK) タイトルにおいてネットワークの接続状態や初期化情報を取得する方法について解説します。GDK タイトルは、コア OS コンポーネントやネットワーク サービスが起動する前に起動されることがよくあります。そのため、タイトル起動直後に `WinSock`、`WinHTTP`、`BCrypt`、`WinCrypt`、`schannel`、`IPHLPAPI` など、ほとんどのネットワークおよびセキュリティ API を呼び出そうとすると、不定な動作を招く可能性があります。この動作には、予期しない失敗、初期化されていない戻り値、任意のパケット ロス、メモリ破損やクラッシュなどが含まれます。

このような不定な動作を回避するため、Microsoft Game Development Kit (GDK) タイトルでは [XNetworkingGetConnectivityHint](/reference/networking/xnetworking/functions/xnetworkinggetconnectivityhint) と [XNetworkingRegisterConnectivityHintChanged](/reference/networking/xnetworking/functions/xnetworkingregisterconnectivityhintchanged) 関数を使用してください。特に、`XNetworkingConnectivityHint::networkInitialized` フィールドはネットワークが初期化済みかどうかを示します。タイトルは、ネットワークおよびセキュリティ API を呼び出す前に、`networkInitialized` フィールドが `true` になるのを待つ必要があります。

多くのミドルウェア ライブラリも内部でネットワーク API やセキュリティ API を使用します。ネットワーク以外のミドルウェアであっても、テレメトリやデバッグ用にネットワーク スタックを使用する場合があります。各ケースでどう対応すべきかは、ミドルウェア提供元に確認してください。ミドルウェア自身がネットワーク初期化を待機しない場合、ネットワークが初期化されるまでミドルウェアのロードを遅延させる必要があります。Microsoft Game Development Kit (GDK) 内のいくつかのライブラリ、たとえば [XSAPI](https://learn.microsoft.com/windows/uwp/xbox-live/xsapi-flat-c) や [Azure PlayFab Party](/build/console-features/networking/game-mesh/playfab-party-intro-networking) は、使用前にネットワークの初期化を待機する必要があります。

## HTTP スタックのシーケンス

このドキュメント セット内で、ネットワーク初期化を自動的に管理する HTTP ライブラリは `xCurl` と `libHttpClient` だけです。タイトルがそれ以外の HTTP スタックを使用する場合は、起動シーケンスを明示的に記述してください。安全なパターンは次のとおりです。

1. 現在の接続ヒントを問い合わせるか、接続変更のリスナーを登録する。
2. `XNetworkingConnectivityHint::networkInitialized` が `true` になるまで待機する。
3. `WinSock` およびその他のネットワーク依存関係を初期化する。
4. 証明書の状態にアクセスし、信頼設定を構成する。
5. HTTP スタックを作成し、リクエストの発行を開始する。

ネットワーク準備が最優先です。`WinSock`、証明書の状態、または HTTP の状態を早期に立ち上げると、目に見えるエラーが根本原因よりも遅れて発生することが多いため、原因の特定が困難になります。

次の例は、タイトルが所有する HTTP スタックの起動シーケンスの最初の数ステップを示しています。この例では、`WinSock` を起動する直前に `XNetworkingConnectivityHint` を直接問い合わせています。

```cpp theme={null}
HRESULT InitializeNetworkingDependencies()
{
    XNetworkingConnectivityHint connectivityHint{};
    HRESULT hr = XNetworkingGetConnectivityHint(&connectivityHint);
    if (FAILED(hr))
    {
        return hr;
    }

    if (!connectivityHint.networkInitialized)
    {
        // Try again after your title receives a connectivity change notification.
        return E_PENDING;
    }

    WSADATA wsaData{};
    int winsockResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
    if (winsockResult != 0)
    {
        return HRESULT_FROM_WIN32(winsockResult);
    }

    return S_OK;
}
```

これらの手順が成功したら、HTTP スタックのオブジェクトを作成し、リクエストを発行する前にスタック固有の信頼設定を適用します。Schannel 以外のスタックの場合、これにはデバッグ ツールが必要とするプロキシ証明書のロードが含まれることがあります。

## サスペンドとレジューム

さらに、タイトルのサスペンド/レジューム サイクルによって `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 または同等の復元フロー
* サスペンドおよびレジュームの境界周辺でのネットワーク切断

## ネットワーク初期化のコード例

次のコード例は、リアルタイム安全な方法でネットワークが初期化されているかどうかをポーリングする方法を示しています。

```cpp theme={null}

bool IsNetworkInitialized()
{
    XNetworkingConnectivityHint connectivityHint;
    if (SUCCEEDED(XNetworkingGetConnectivityHint(&connectivityHint)))
    {
        return connectivityHint.networkInitialized;
    }
    return false;
}

```

次のコード例は、ネットワークが初期化されるまでタイトルがブロックする方法を示しています。

```cpp theme={null}
static
void
NetworkConnectivityHintChangedCallback(
    _In_ void* context,
    _In_ const XNetworkingConnectivityHint* connectivityHint
    )
{
    HANDLE networkInitializedEvent = static_cast<HANDLE>(context);
    if (connectivityHint->networkInitialized)
    {
        (void)SetEvent(networkInitializedEvent);
    }
}

HRESULT EnsureNetworkInitialized()
{
    HRESULT hr = S_OK;
    XNetworkingConnectivityHint connectivityHint;
    XTaskQueueHandle queue;

    hr = XTaskQueueCreate(XTaskQueueDispatchMode::Immediate, XTaskQueueDispatchMode::Immediate, &queue);
    if (SUCCEEDED(hr))
    {
        // Use the new XNetworking APIs to check if the network is initialized.
        hr = XNetworkingGetConnectivityHint(&connectivityHint);
        if (SUCCEEDED(hr))
        {
            if (!connectivityHint.networkInitialized)
            {
                // The network isn't initialized. Wait until the network becomes initialized.
                HANDLE networkInitializedEvent = CreateEvent(nullptr, TRUE, FALSE, nullptr);
                if (networkInitializedEvent != nullptr)
                {
                    XTaskQueueRegistrationToken token;
                    hr = XNetworkingRegisterConnectivityHintChanged(queue, networkInitializedEvent, NetworkConnectivityHintChangedCallback, &token);
                    if (SUCCEEDED(hr))
                    {
                        DWORD result = WaitForSingleObjectEx(networkInitializedEvent, INFINITE, FALSE);
                        if (result != WAIT_OBJECT_0)
                        {
                            hr = HRESULT_FROM_WIN32(GetLastError());
                        }

                        XNetworkingUnregisterConnectivityHintChanged(token, true);
                    }

                    CloseHandle(networkInitializedEvent);
                }
                else
                {
                    hr = HRESULT_FROM_WIN32(GetLastError());
                }
            }
        }

        XTaskQueueCloseHandle(queue);
    }

    return hr;
}

```

## ネットワーク情報

Microsoft Game Development Kit (GDK) タイトルにおけるネットワーク情報は、[XNetworkingGetConnectivityHint](/reference/networking/xnetworking/functions/xnetworkinggetconnectivityhint) API で取得できます。

[XNetworkingGetConnectivityHint](/reference/networking/xnetworking/functions/xnetworkinggetconnectivityhint) API は、デバイス全体のネットワーク接続レベル、データ制限、有線と無線の接続タイプ、およびネットワーク初期化状態などの情報を返します。これは現在の情報をただちに返す、リアルタイム安全な API です。変更の受信には、[XNetworkingRegisterConnectivityHintChanged](/reference/networking/xnetworking/functions/xnetworkingregisterconnectivityhintchanged) および [XNetworkingUnregisterConnectivityHintChanged](/reference/networking/xnetworking/functions/xnetworkingunregisterconnectivityhintchanged) 関数を使用します。

次のコード例は、[XNetworkingGetConnectivityHint](/reference/networking/xnetworking/functions/xnetworkinggetconnectivityhint) 関数を使用して現在のネットワーク状態に関する情報を照会する方法を示しています。

```cpp theme={null}

XNetworkingConnectivityHint connectivityHint;
if (SUCCEEDED(XNetworkingGetConnectivityHint(&connectivityHint)))
{
    printf(L"network initialized %u\n", connectivityHint.networkInitialized);
    printf(L"network connectivity level hint %u\n", connectivityHint.connectivityLevel);
    printf(L"network connectivity cost hint %u\n", connectivityHint.connectivityCost);
    printf(L"network approaching data limit %u\n", connectivityHint.approachingDataLimit);
    printf(L"network over data limit %u\n", connectivityHint.overDataLimit);
    printf(L"device is roaming %u\n", connectivityHint.roaming);
    switch (connectivityHint.ianaInterfaceType) {
    case IF_TYPE_ETHERNET_CSMACD:
        printf(L"network type is wired\n");
            break;
    case IF_TYPE_IEEE80211:
        printf(L"network type is wireless\n");
        break;
    case IF_TYPE_WWANPP:
    case IF_TYPE_WWANPP2:
        printf(L"network type is broadband\n");
        break;
    default:
        printf(L"network type is unusually esoteric %u\n", connectivityHint.connectivityLevel);
        break;
    }
}

```

## ネットワーク接続のベスト プラクティス

返される [XNetworkingConnectivityHint](/reference/networking/xnetworking/structs/xnetworkingconnectivityhint) 構造体のうち、`XNetworkingConnectivityHint::networkInitialized` 以外のフィールドはヒントです。これらは、デバイスが観測したネットワーク トラフィックのヒューリスティックに基づく、ネットワーク現在の状態のベスト エフォート推測です。

`XNetworkingConnectivityLevelHint` の状態は、タイトルの接続ロジックを単純化するための一般的なネットワーク レベルの近似を表します。タイトルは、ネットワーク環境が数分間変化していない安定状態でネットワーク メディアの切断や一般的な接続不足を反映するものとして `XNetworkingConnectivityLevelHint::None` を扱うことができます。それ以外の状態は、タイトル固有のエンドポイントへの接続性を表すものではありません。

そのため、ネットワーク初期化を待った後は、`XNetworkingConnectivityHint::connectivityLevelHint` フィールドの状態にかかわらず、`WinSock` や `WinHTTP` を使ってエンドポイントへの接続確立を試みることを推奨します。それらの API が後で失敗した場合は、UI 表示や診断報告用に [XNetworkingGetConnectivityHint](/reference/networking/xnetworking/functions/xnetworkinggetconnectivityhint) API を使用してください。そして、ネットワーク接続レベルが変化するのを待ってから再試行します。

## 高度なネットワーク情報の取得

ほとんどの Microsoft Game Development Kit (GDK) タイトルでは、ネットワークの状態や IP アドレスなどの基本情報の取得には、[XNetworkingGetConnectivityHint](/reference/networking/xnetworking/functions/xnetworkinggetconnectivityhint) API と `WinSock` API を組み合わせて使用してください。さらに詳しい情報が必要な場合は、GDK で低レベルの [IP Helper API](https://learn.microsoft.com/windows/desktop/IpHlp/ip-helper-start-page) が利用可能です。

一般的に、Microsoft Game Development Kit (GDK) での `IP Helper` API の扱い方は、Win32 プログラムでの扱い方と同じです。

1. ソース ファイルで、`#include <winsock2.h>` の後に `#include <iphlpapi.h>` を記述します。

2. `Ws2_32.lib` と `Iphlpapi.lib` を直接リンクする代わりに、`XGamePlatform.lib` にリンクします。

Microsoft Game Development Kit (GDK) タイトルでは、`WINAPI\_PARTITION\_GAMES` API ファミリの API のみが動作します。

XBOX コンソールでは、基盤となるプラットフォーム抽象化のために、`IP Helper` API を使用しても正確でない情報があります。これには、次のような例が含まれますが、これらに限りません。

* MAC アドレスは常に `AA-AA-AA-AA-AA-AA` です。
* すべてのインターフェイスは、基盤となるネットワーク接続タイプに関係なく、常に有線インターフェイスとして報告されます。実際のインターフェイス タイプは [XNetworkingGetConnectivityHint](/reference/networking/xnetworking/functions/xnetworkinggetconnectivityhint) からのみ取得できます。

## サポートされていないネットワーク接続 API

以下のネットワーク接続 API は Microsoft Game Development Kit (GDK) タイトルではサポートされていません。ネットワーク接続の判定には代わりに [XNetworkingGetConnectivityHint](/reference/networking/xnetworking/functions/xnetworkinggetconnectivityhint) API を使用してください。

* [Windows.Networking.Connectivity Namespace](https://learn.microsoft.com/uwp/api/windows.networking.connectivity)

* [Network List Manager](https://learn.microsoft.com/windows/desktop/nla/portal)

## 関連項目

[XNetworkingGetConnectivityHint](/reference/networking/xnetworking/functions/xnetworkinggetconnectivityhint)

[XNetworkingRegisterConnectivityHintChanged](/reference/networking/xnetworking/functions/xnetworkingregisterconnectivityhintchanged)

[XNetworkingUnregisterConnectivityHintChanged](/reference/networking/xnetworking/functions/xnetworkingunregisterconnectivityhintchanged)

[Windows Sockets 2 (Winsock)](https://learn.microsoft.com/windows/desktop/WinSock/windows-sockets-start-page-2)

[Windows HTTP Services (WinHTTP)](https://learn.microsoft.com/windows/desktop/winhttp/winhttp-start-page)

[IP Helper API](https://learn.microsoft.com/windows/desktop/IpHlp/ip-helper-start-page)


## Related topics

- [優先ローカル UDP マルチプレイヤー ポート ネットワーキング API](/ja-jp/build/console-features/networking/game-mesh/preferred-local-udp-multiplayer-port-networking.md)
- [GDK による XBOX コンソールでのネットワーク](/ja-jp/build/console-features/networking/index.md)
- [Microsoft Game Development Kit ネットワークの概要](/ja-jp/build/console-features/networking/introduction-networking.md)
- [GDK と XDK における Web リクエストの相違点](/ja-jp/build/console-features/networking/xdk-migration/xdk-migration-web-requests-networking.md)
- [ゲーム メッシュ通信: GDK と XDK の相違点](/ja-jp/build/console-features/networking/xdk-migration/xdk-migration-game-mesh-networking.md)
