> For the complete documentation index, see [llms.txt](/llms.txt)

# GS2-Gateway SDK for Game Engine API リファレンス

ゲームエンジン向け GS2-Gateway SDK の モデルの仕様 と API のリファレンス



## モデル

### EzWebSocketSession

WebSocketSession<br>

WebSocketセッションはGS2サーバとクライアント間の持続的な接続で、リアルタイムに双方向通信を行います。<br>
サーバに対してクライアント側から識別子としてユーザーIDを登録します。

|  | 型 | 有効化条件 | 必須 | デフォルト | 値の制限 | 説明 |
| --- | --- | --- | --- | --- | --- | --- |
| connectionId | string |  | ✓ |  |  ~ 128文字 | コネクションID<br>この WebSocket 接続に割り当てられた一意な識別子です。通知送信時に特定のクライアント接続を識別するために使用されます。 |
| namespaceName | string |  | ✓ |  |  ~ 128文字 | ネームスペース名 |
| userId | string |  | ✓ |  |  ~ 128文字 | ユーザーID |

**関連するメソッド:**
setUserId - サーバーからのプッシュ通知を受け取るためにプレイヤーの接続を登録する


---

### EzFirebaseToken

Firebaseデバイストークン<br>

Firebaseデバイストークンはモバイルプッシュ通知を利用する際に必要となります。<br>

GS2-Gateway はゲーム内プッシュ通知機能を提供し、マッチメイキング完了時やミッション達成時にプッシュ通知を受けられますが<br>
通知先のプレイヤーがオフラインだった場合にモバイルプッシュ通知に転送することができます。<br>

その時に通知先のデバイスを特定し、通知するのに使用するのが Firebaseデバイストークン です。<br>
名前の通り Firebase という外部サービスを利用するため、トークンの取得方法などの詳細情報は Firebase のドキュメントをご確認ください。

|  | 型 | 有効化条件 | 必須 | デフォルト | 値の制限 | 説明 |
| --- | --- | --- | --- | --- | --- | --- |
| userId | string |  | ✓ |  |  ~ 128文字 | ユーザーID |
| token | string |  | ✓ |  |  ~ 1024文字 | Firebase Cloud Messaging のデバイストークン<br>クライアントデバイスから取得した FCM 登録トークンです。プレイヤーがオフラインでゲーム内の WebSocket 通知を受信できない場合に、モバイルプッシュ通知を配信する特定のデバイスを識別します。トークンはデバイス固有で、アプリの再インストールやデータのクリア時に変更される場合があります。 |
| locale | string |  |  |  |  ~ 32文字 | 通知メッセージのロケール<br>このデバイスに届ける通知メッセージのロケールです。`ja` / `en` のような自由形式の文字列で、決まった値の一覧に限定されません。通知がモバイルプッシュ通知に転送される際、ペイロードが `{locale, message}` の要素を持つ `mobile` 配列を含む JSON である場合、このロケールに一致する要素がプッシュ通知の本文として使用されます。一致する要素がない場合は `default` のロケールを持つ要素が、それも無い場合は配列の先頭の要素が使用されます。ペイロードがその形式でない場合はペイロードがそのまま使用されます。この項目は任意で、設定されていない場合は `default` の要素・先頭の要素・ペイロードそのものだけが適用されます。 |

**関連するメソッド:**
getFirebaseToken - プレイヤーに登録されているデバイストークンを取得する
setFirebaseToken - モバイルプッシュ通知の配信先となるデバイストークンを登録する
deleteFirebaseToken - この端末へのモバイルプッシュ通知の配信を止める


---

## メソッド

### setUserId

サーバーからのプッシュ通知を受け取るためにプレイヤーの接続を登録する<br>

現在のWebSocket接続をプレイヤーのユーザーIDに紐づけて、サーバーからこのクライアントにリアルタイムのプッシュ通知を送信できるようにします。<br>
通常はプレイヤーがログインしてサーバーに接続した直後に呼び出します。このステップなしでは、サーバーはどの接続がどのプレイヤーのものか判別できません。<br>
allowConcurrentAccess フラグで、同じプレイヤーが複数のデバイスから同時に接続できるかを制御します：<br>
- true: 複数の同時接続を許可（スマホとタブレットの両方でプレイするなど）<br>
- false: プレイヤーごとに1接続のみ許可（重複ログイン防止。古い接続は切断されます）<br>
ゲームのログイン・初期化フローの一部として使います。リアルタイムチャット通知、フレンドリクエストのアラート、マッチング成立の通知などの機能を有効にするのに必要です。

#### Request

|  | 型 | 有効化条件 | 必須 | デフォルト | 値の制限 | 説明 |
| --- | --- | --- | --- | --- | --- | --- |
| namespaceName | string |  | ✓|  |  ~ 128文字 | ネームスペース名 |
| gameSession | GameSession | | ✓|  |  | GameSession |
| allowConcurrentAccess | bool |  | | true |  | 同時に異なるクライアントからの接続を許容するか |
| sessionId | string | {allowConcurrentAccess} == false | |  |  ~ 128文字 | allowConcurrentAccess を false にした場合でも、既存接続と同一の sessionId であれば接続を許可するために指定します。 |

#### Result

|  | 型 | 説明 |
| --- | --- | --- |
| item | [EzWebSocketSession](#ezwebsocketsession) | 更新したWebSocketセッション|

#### 実装例




**Unity (UniTask)**
```csharp
    var domain = gs2.Gateway.Namespace(
        namespaceName: "$hash"
    ).Me(
        gameSession: GameSession
    ).WebSocketSession(
    );
    var result = await domain.SetUserIdAsync(
        allowConcurrentAccess: true,
        sessionId: null
    );
    var item = await result.ModelAsync();

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Gateway.Namespace(
        namespaceName: "$hash"
    ).Me(
        gameSession: GameSession
    ).WebSocketSession(
    );
    var future = domain.SetUserIdFuture(
        allowConcurrentAccess: true,
        sessionId: null
    );
    yield return future;
    if (future.Error != null)
    {
        onError.Invoke(future.Error, null);
        yield break;
    }
    var future2 = future.Result.ModelFuture();
    yield return future2;
    if (future2.Error != null)
    {
        onError.Invoke(future2.Error, null);
        yield break;
    }
    var result = future2.Result;

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Gateway->Namespace(
        "$hash" // namespaceName
    )->Me(
        GameSession
    )->WebSocketSession(
    );
    const auto Future = Domain->SetUserId(
        true // allowConcurrentAccess
        // sessionId
    );
    Future->StartSynchronousTask();
    if (Future->GetTask().IsError())
    {
        return false;
    }

    // 変更された値 / 結果の値を取得
    const auto Future2 = Future->GetTask().Result()->Model();
    Future2->StartSynchronousTask();
    if (Future2->GetTask().IsError())
    {
        return Future2->GetTask().Error();
    }
    const auto Result = Future2->GetTask().Result();

```

**Godot**
```gdscript

var domain = ez.gateway.namespace_(
        "$hash"
    ).me(game_session).web_socket_session(
    )

var async_result = await domain.set_user_id(
    true, # allow_concurrent_access
    null # session_id
)
if async_result.error != null:
    push_error(str(async_result.error))
    return

var result = async_result.result

```


---

### deleteFirebaseToken

この端末へのモバイルプッシュ通知の配信を止める<br>

プレイヤーに登録されている FCM デバイストークンを削除します。<br>
削除するとオフライン時に届いた通知がモバイルプッシュ通知へ転送されなくなり、ゲーム内の WebSocket 通知のみになります。<br>
プレイヤーがログアウトするとき（共用端末で次のプレイヤーに前のプレイヤー宛ての通知が届かないようにするため）や、ゲームの設定画面でプレイヤーが通知をオフにしたときに呼び出してください。<br>
トークンを削除してもアカウントの他の情報には影響しません。再びトークンを登録すればモバイルプッシュ通知の受信を再開できます。

#### Request

|  | 型 | 有効化条件 | 必須 | デフォルト | 値の制限 | 説明 |
| --- | --- | --- | --- | --- | --- | --- |
| namespaceName | string |  | ✓|  |  ~ 128文字 | ネームスペース名<br>ネームスペース固有の名前。英数字および -(ハイフン) _(アンダースコア) .(ピリオド)で指定します。 |
| gameSession | GameSession | | ✓|  |  | GameSession |

#### Result

|  | 型 | 説明 |
| --- | --- | --- |
| item | [EzFirebaseToken](#ezfirebasetoken) | 削除したFirebaseデバイストークン|

#### 実装例




**Unity (UniTask)**
```csharp
    var domain = gs2.Gateway.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).FirebaseToken(
    );
    var result = await domain.DeleteFirebaseTokenAsync(
    );

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Gateway.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).FirebaseToken(
    );
    var future = domain.DeleteFirebaseTokenFuture(
    );
    yield return future;
    if (future.Error != null)
    {
        onError.Invoke(future.Error, null);
        yield break;
    }

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Gateway->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        GameSession
    )->FirebaseToken(
    );
    const auto Future = Domain->DeleteFirebaseToken(
    );
    Future->StartSynchronousTask();
    if (Future->GetTask().IsError())
    {
        return false;
    }
    const auto Result = Future->GetTask().Result();

```

**Godot**
```gdscript

var domain = ez.gateway.namespace_(
        "namespace-0001"
    ).me(game_session).firebase_token(
    )

var async_result = await domain.delete_firebase_token(
)
if async_result.error != null:
    push_error(str(async_result.error))
    return

var result = async_result.result

```


---

### getFirebaseToken

プレイヤーに登録されているデバイストークンを取得する<br>

プレイヤーに現在登録されている FCM デバイストークンを取得します。<br>
この端末ですでにトークンを登録済みかどうかを確認するのに使います。たとえば通知の許可を求めてトークンを登録する必要があるかの判断や、「通知設定」画面で現在の状態を表示するのに利用できます。<br>
トークンが未登録の場合はリクエストが not found エラーになるので、そのケースは「まだ通知の設定がされていない」として扱ってください。<br>
登録されているトークンはプレイヤーが以前に使っていた別の端末のものである可能性もあるため、この端末で Firebase SDK から取得したトークンと比較したうえで登録を省略するか判断してください。

#### Request

|  | 型 | 有効化条件 | 必須 | デフォルト | 値の制限 | 説明 |
| --- | --- | --- | --- | --- | --- | --- |
| namespaceName | string |  | ✓|  |  ~ 128文字 | ネームスペース名<br>ネームスペース固有の名前。英数字および -(ハイフン) _(アンダースコア) .(ピリオド)で指定します。 |
| gameSession | GameSession | | ✓|  |  | GameSession |

#### Result

|  | 型 | 説明 |
| --- | --- | --- |
| item | [EzFirebaseToken](#ezfirebasetoken) | Firebaseデバイストークン|

#### 実装例




**Unity (UniTask)**
```csharp
    var domain = gs2.Gateway.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).FirebaseToken(
    );
    var item = await domain.ModelAsync();

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Gateway.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).FirebaseToken(
    );
    var future = domain.ModelFuture();
    yield return future;
    var item = future.Result;

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Gateway->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        GameSession
    )->FirebaseToken(
    );
    const auto Future = Domain->Model();
    Future->StartSynchronousTask();
    if (Future->GetTask().IsError())
    {
        return false;
    }

```

**Godot**
```gdscript

var domain = ez.gateway.namespace_(
        "namespace-0001"
    ).me(game_session).firebase_token(
    )

var async_result = await domain.model()
if async_result.error != null:
    push_error(str(async_result.error))
    return

var result = async_result.result

```


##### 値の変更イベントハンドリング




**Unity (UniTask)**
```csharp
    var domain = gs2.Gateway.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).FirebaseToken(
    );
    
    // イベントハンドリングを開始
    var callbackId = domain.Subscribe(
        value => {
            // 値が変化した時に呼び出される
            // value には変更後の値が渡ってくる
        }
    );

    // イベントハンドリングを停止
    domain.Unsubscribe(callbackId);

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Gateway.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).FirebaseToken(
    );
    
    // イベントハンドリングを開始
    var callbackId = domain.Subscribe(
        value => {
            // 値が変化した時に呼び出される
            // value には変更後の値が渡ってくる
        }
    );

    // イベントハンドリングを停止
    domain.Unsubscribe(callbackId);

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Gateway->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        GameSession
    )->FirebaseToken(
    );
    
    // イベントハンドリングを開始
    const auto CallbackId = Domain->Subscribe(
        [](TSharedPtr<Gs2::Gateway::Model::FFirebaseToken> value) {
            // 値が変化した時に呼び出される
            // value には変更後の値が渡ってくる
        }
    );

    // イベントハンドリングを停止
    Domain->Unsubscribe(CallbackId);

```

**Godot**
```gdscript

var domain = ez.gateway.namespace_(
        "namespace-0001"
    ).me(game_session).firebase_token(
    )

# イベントハンドリングを開始
var callback_id = domain.subscribe_model(func(value):
    # 値が変化した時に呼び出される
    # value には変更後の値が渡されます
    pass
)

# イベントハンドリングを停止
domain.unsubscribe_model(callback_id)

```


**⚠️ Warning**

このイベントはSDKがもつローカルキャッシュの値が変更された時に呼び出されます。

ローカルキャッシュは SDK が持つ API の実行、または GS2-Gateway の通知を有効にした GS2-Distributor 経由でのスタンプシートの実行、または GS2-Gateway の通知を有効にした GS2-JobQueue の実行によって変化したもののみが対象となります。

そのため、これらの方法以外で値が変更されてもコールバックは呼び出されません。

---

### setFirebaseToken

モバイルプッシュ通知の配信先となるデバイストークンを登録する<br>

プレイヤーの端末で Firebase SDK から取得した FCM デバイストークンを登録（更新）します。<br>
サーバーからのプッシュ通知は通常プレイヤーの WebSocket 接続を通じて配信されますが、プレイヤーがオフラインで WebSocket セッションがない場合には、ここで登録したトークンを使ってモバイルプッシュ通知に転送されます。<br>
これにより、ゲームを閉じているプレイヤーにも「マッチメイキングが成立した」「スタミナが全回復した」「フレンド申請が届いた」といった通知を届けられます。<br>
ログイン直後に Firebase SDK からトークンを受け取ったタイミングで呼び出し、さらに Firebase からトークンのリフレッシュが通知されるたびに呼び出してください。トークンは端末固有で、アプリの再インストールやデータのクリア、Firebase 側のローテーションによって変化します。<br>
すでにトークンが登録されている場合は上書きされるだけなので、ゲーム起動のたびに呼び出しても問題ありません。<br>
`locale` にはプレイヤーの言語設定（たとえば `ja` や `en`）を渡してください。通知のペイロードに複数言語のメッセージが含まれている場合に、そのロケールに一致するメッセージがモバイルプッシュ通知に使われます。

#### Request

|  | 型 | 有効化条件 | 必須 | デフォルト | 値の制限 | 説明 |
| --- | --- | --- | --- | --- | --- | --- |
| namespaceName | string |  | ✓|  |  ~ 128文字 | ネームスペース名<br>ネームスペース固有の名前。英数字および -(ハイフン) _(アンダースコア) .(ピリオド)で指定します。 |
| gameSession | GameSession | | ✓|  |  | GameSession |
| token | string |  | ✓|  |  ~ 1024文字 | Firebase Cloud Messaging のデバイストークン<br>クライアントデバイスから取得した FCM 登録トークンです。プレイヤーがオフラインでゲーム内の WebSocket 通知を受信できない場合に、モバイルプッシュ通知を配信する特定のデバイスを識別します。トークンはデバイス固有で、アプリの再インストールやデータのクリア時に変更される場合があります。 |
| locale | string |  | |  |  ~ 32文字 | 通知メッセージのロケール<br>このデバイスに届ける通知メッセージのロケールです。`ja` / `en` のような自由形式の文字列で、決まった値の一覧に限定されません。通知がモバイルプッシュ通知に転送される際、ペイロードが `{locale, message}` の要素を持つ `mobile` 配列を含む JSON である場合、このロケールに一致する要素がプッシュ通知の本文として使用されます。一致する要素がない場合は `default` のロケールを持つ要素が、それも無い場合は配列の先頭の要素が使用されます。ペイロードがその形式でない場合はペイロードがそのまま使用されます。この項目は任意で、設定されていない場合は `default` の要素・先頭の要素・ペイロードそのものだけが適用されます。 |

#### Result

|  | 型 | 説明 |
| --- | --- | --- |
| item | [EzFirebaseToken](#ezfirebasetoken) | 作成したFirebaseデバイストークン|

#### 実装例




**Unity (UniTask)**
```csharp
    var domain = gs2.Gateway.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).FirebaseToken(
    );
    var result = await domain.SetFirebaseTokenAsync(
        token: "firebase-token-0001",
        locale: null
    );
    var item = await result.ModelAsync();

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Gateway.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).FirebaseToken(
    );
    var future = domain.SetFirebaseTokenFuture(
        token: "firebase-token-0001",
        locale: null
    );
    yield return future;
    if (future.Error != null)
    {
        onError.Invoke(future.Error, null);
        yield break;
    }
    var future2 = future.Result.ModelFuture();
    yield return future2;
    if (future2.Error != null)
    {
        onError.Invoke(future2.Error, null);
        yield break;
    }
    var result = future2.Result;

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Gateway->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        GameSession
    )->FirebaseToken(
    );
    const auto Future = Domain->SetFirebaseToken(
        "firebase-token-0001" // token
        // locale
    );
    Future->StartSynchronousTask();
    if (Future->GetTask().IsError())
    {
        return false;
    }

    // 変更された値 / 結果の値を取得
    const auto Future2 = Future->GetTask().Result()->Model();
    Future2->StartSynchronousTask();
    if (Future2->GetTask().IsError())
    {
        return Future2->GetTask().Error();
    }
    const auto Result = Future2->GetTask().Result();

```

**Godot**
```gdscript

var domain = ez.gateway.namespace_(
        "namespace-0001"
    ).me(game_session).firebase_token(
    )

var async_result = await domain.set_firebase_token(
    "firebase-token-0001", # token
    null # locale
)
if async_result.error != null:
    push_error(str(async_result.error))
    return

var result = async_result.result

```


---



