GS2-Gateway

WebSocket 通知機能

GS2-Gateway はゲームクライアントとサーバーとの間で WebSocket による常時接続を維持し、サーバーから任意のタイミングで通知を送るための機能を提供します。

通常のゲームサーバーとの通信はクライアントからのリクエストに対してサーバーが応答する形式ですが、GS2-Gateway を使うことでサーバー起点の通知 (メッセージ着信・フレンド申請・ギルドからの招集など) をリアルタイムにクライアントへ届けることができます。

sequenceDiagram
  participant Client
  participant Gateway as GS2-Gateway
  participant Service as 各マイクロサービス

  Client->>Gateway: WebSocket 接続
  Client->>Gateway: SetUserId(認証)
  Service->>Gateway: SendNotification
  Gateway->>Client: 通知ペイロード配信

主な機能

WebSocket 常時接続

GS2-Gateway は WebSocket プロトコルでクライアントからの接続を受け付け、ユーザーごとに接続情報を保持します。 他のマイクロサービスから「このユーザーに通知を送りたい」というリクエストが届くと、接続中のクライアントに対してペイロードを配信します。

主要な連携先は以下です。

  • GS2-Inbox: 新規メッセージの着信通知
  • GS2-Friend: フレンド申請・承認の通知
  • GS2-Guild: ギルド参加申請、ギルド内の状況変化通知
  • GS2-Matchmaking: マッチング完了通知
  • GS2-Distributor: トランザクション自動実行のための通知
  • GS2-JobQueue: 新規ジョブが積まれた際の通知

同時接続制御

ネームスペース内のユーザーは原則として同時に1セッションのみを保持できます。

SetUserId 実行時に allowConcurrentAccessfalse にすると、すでに他のセッションが接続中の場合は、新しいセッション側で同時接続エラーとして検知できます。 true にすると、新しいセッションが接続された時点で古いセッションが切断されます。

この機能を利用することで、複数デバイスからの同時ログインを抑止できます。 GS2-Account のパスワード自動変更機能と組み合わせると、アカウント共有や引き継ぎ後の旧デバイスの締め出しをより強固に行うことができます。

Firebase Cloud Messaging 連携 (モバイルプッシュ通知)

クライアントが起動していない (WebSocket が接続されていない) 状態でも通知を届けたい場合は、Firebase Cloud Messaging (FCM) との連携機能を利用できます。

事前にネームスペースの firebaseSecret に FCM のサーバーキー(またはサービスアカウントクレデンシャル)を登録しておき、各ユーザーのデバイスから取得した FCM トークンを GS2-Gateway に登録しておきます。

GS2-Gateway は、通知配信時に WebSocket セッションが存在しないユーザーに対しては、登録済みの FCM トークンを使って FCM 経由でプッシュ通知を送ります。 これによりアプリ未起動時でもユーザーに通知を届けることができます。

通知エントリの enableTransferMobileNotification を有効にすることで、各通知ごとにモバイルプッシュへの転送有無を制御できます。

WebSocket API の設定

GS2 のクライアント SDK (Unity / Unreal Engine) には、GS2-Gateway の WebSocket 接続を自動的に確立・維持するユーティリティが組み込まれています。

ログイン時に GatewaySetting を指定することで、ログイン処理の流れに乗せて WebSocket 接続と SetUserId の呼び出しを自動的に行えます。

設定項目は以下の通りです。

  • gatewayNamespaceName: 使用する GS2-Gateway のネームスペース名
  • allowConcurrentAccess: 同時接続を許可するかどうか

トランザクションアクション

GS2-Gateway ではトランザクションアクションを提供していません。

マスターデータ管理

GS2-Gateway はマスターデータを持ちません。 ネームスペースの設定で Firebase 連携情報やログ設定を構成します。

実装例

ログイン時に WebSocket 接続を確立

GatewaySetting を指定してログインすると、SDK が自動的に WebSocket セッションを確立し、SetUserId を呼び出してユーザーIDを紐付けます。

    var gameSession = await gs2.LoginAsync(
        new Gs2AccountAuthenticator(
            accountSetting: new AccountSetting {
                accountNamespaceName = this.accountNamespaceName,
            },
            gatewaySetting: new GatewaySetting {
                gatewayNamespaceName = "namespace-0001",
                allowConcurrentAccess = false,
            }
        ),
        account.UserId,
        account.Password
    );
    const auto Future = Profile->Login(
        MakeShareable<Gs2::UE5::Util::IAuthenticator>(
            new Gs2::UE5::Util::FGs2AccountAuthenticator(
                AccountNamespaceName,
                KeyId,
                "namespace-0001", // gatewayNamespaceName
                false             // allowConcurrentAccess
            )
        ),
        UserId,
        Password
    );

    Future->StartSynchronousTask();
    if (Future->GetTask().IsError()) return false;
    const auto Result = Future->GetTask().Result();

明示的にユーザーIDを設定

すでに接続している WebSocket セッションに対してユーザーIDを紐付けたい場合や、ログイン後に同時接続の許可状態を変更したい場合は、SetUserId を呼び出します。

    var domain = await gs2.Gateway.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).WebSocketSession(
    ).SetUserIdAsync(
        allowConcurrentAccess: false
    );
    const auto Future = Gs2->Gateway->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        GameSession
    )->WebSocketSession(
    )->SetUserId(
        false // allowConcurrentAccess
    );
    Future->StartSynchronousTask();
    if (Future->GetTask().IsError()) return false;

より実践的な情報

同時接続切断のハンドリング

allowConcurrentAccess: false の設定で接続中に、別端末で同一ユーザーがログインを行うと、現在の WebSocket セッションが切断されます。 クライアントは切断イベントを検知して、再ログインを促す画面に遷移する、または「他の端末でログインされました」というメッセージを表示するといった対応を行う必要があります。

これにより、複数端末からの同時プレイを実質的に禁止する運用が可能になります。

バージョン更新時の全プレイヤー切断

GS2-Version と組み合わせ、新バージョン公開時に全プレイヤーの WebSocket セッションを切断することで、再接続のタイミングで強制的にバージョンチェックを通過させる運用が可能です。

詳細は GS2-Version の「バージョン更新の運用手順」を参照してください。

詳細なリファレンス