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

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

モデル

EzWebSocketSession

WebSocketSession

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

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

EzFirebaseToken

Firebaseデバイストークン

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

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

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

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

メソッド

setUserId

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

現在のWebSocket接続をプレイヤーのユーザーIDに紐づけて、サーバーからこのクライアントにリアルタイムのプッシュ通知を送信できるようにします。
通常はプレイヤーがログインしてサーバーに接続した直後に呼び出します。このステップなしでは、サーバーはどの接続がどのプレイヤーのものか判別できません。
allowConcurrentAccess フラグで、同じプレイヤーが複数のデバイスから同時に接続できるかを制御します:

  • true: 複数の同時接続を許可(スマホとタブレットの両方でプレイするなど)
  • false: プレイヤーごとに1接続のみ許可(重複ログイン防止。古い接続は切断されます)
    ゲームのログイン・初期化フローの一部として使います。リアルタイムチャット通知、フレンドリクエストのアラート、マッチング成立の通知などの機能を有効にするのに必要です。

Request

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

Result

型説明
itemEzWebSocketSession更新したWebSocketセッション

実装例

    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();
    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;
    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();
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

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

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

Request

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

Result

型説明
itemEzFirebaseToken削除したFirebaseデバイストークン

実装例

    var domain = gs2.Gateway.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).FirebaseToken(
    );
    var result = await domain.DeleteFirebaseTokenAsync(
    );
    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;
    }
    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();
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

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

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

Request

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

Result

型説明
itemEzFirebaseTokenFirebaseデバイストークン

実装例

    var domain = gs2.Gateway.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).FirebaseToken(
    );
    var item = await domain.ModelAsync();
    var domain = gs2.Gateway.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).FirebaseToken(
    );
    var future = domain.ModelFuture();
    yield return future;
    var item = future.Result;
    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;
    }
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
値の変更イベントハンドリング
    var domain = gs2.Gateway.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).FirebaseToken(
    );
    
    // イベントハンドリングを開始
    var callbackId = domain.Subscribe(
        value => {
            // 値が変化した時に呼び出される
            // value には変更後の値が渡ってくる
        }
    );

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

    // イベントハンドリングを停止
    domain.Unsubscribe(callbackId);
    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);
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)

setFirebaseToken

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

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

Request

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

Result

型説明
itemEzFirebaseToken作成したFirebaseデバイストークン

実装例

    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();
    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;
    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();
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