Webhooks

Photon CloudでWebhookを使用するとアプリケーションを拡張でき、ゲームへのプレイヤーの再参加や、プレイヤーおよびゲームデータの保持が可能になります。

Photon WebhookはPhoton Cloudによって特定のURLに送信されるイベント駆動型のHTTP POSTリクエストです。 それぞれのPhoton Webhookは、それぞれ固有のトリガー、データ、目的地へのパスによって定義されます。

Webhook 1.2の新機能はこちらで参照してください。

セットアップ

Photon CloudでWebhookをセットアップするには、ダッシュボードのアプリケーションリストの 管理 リンクをクリックしてください。 Webhooks セクションに新規のWebhookを追加するか、または既存のWebhookを変更してください。

Webhook設定ページで、あらかじめ定義されたプリセットをドロップダウンリストから1つ選択します。 "デモ"プリセットは、開発環境でのみ使用してください。 このプリセットは、利用できる様々な設定の概要や、それらの使用方法を表示する際に使用します。

キー/値のセットを含む文字列を定義してコンフィグレーションをおこないます。 許容されるキーの最大長は256文字、値の最大長は1,024文字型です。

基本設定

  • BaseUrl (必須)
    WebRPCで呼ばれるすべてのメソッドと同様に、利用しているhookをホスティングしているサービスのURLです。 このURLの末尾にスラッシュは記載できません。 コールバックは以下で設定された相対パスURIで受信されます。 設定したい値にクエリ文字列が含まれている場合には、こちらを参照してください。
  • CustomHttpHeaders
    設定されたWebサービスに対して行なわれるすべてのリクエストにHTTPヘッダーとして設定されるべき、キー/値のセットのJSON文字列。 詳細はこちらを参照してください。

パス

ホスト上で識別される各URIでイベントを受け取るために、それぞれのパスを設定します。 空のままのパスを使用するとヒットされず、影響を受けたWebhook上でコールバックを受け取ることはありません。

  • PathCreate
    新規ルームが作成される時や、外部サービスからステートを読み込む必要がある時に呼ばれます。
  • PathClose
    ルームがPhotonサーバーのメモリから削除されると呼ばれます。 IsPersistent_がtrueに設定されている場合には、ルームのステートが送信されます。
  • PathJoin
    ルームがPhotonサーバーのメモリにある際にプレイヤーが参加すると呼ばれます。
  • PathLeave
    プレイヤーがルームを退出するときに呼ばれます。
  • PathEvent
    クライアントが、WebフラグHttpForwardが設定されたルームでイベントを上げた場合に呼ばれます。
  • PathGameProperties
    クライアントが、WebフラグHttpForwardを設定したルームやプレイヤープロパティを設定した場合に呼ばれます。

オプション

これらのオプションを使用すれば、Webhookの動作を微調整できます。 オプションは、設定されていない場合や、値が空の場合には設定されていないとみなされます。 各オプションのデフォルト値はfalseで、値が設定されていない場合に適用されます。

  • HasErrorInfo
    trueに設定すると、hookへのコールが失敗した場合にクライアントにErrorEventが通知されます。
  • IsPersistent
    trueに設定するとPhoton Cloud は、メモリからルームを削除する前にステートを送信します。 このオプションはPathCreateとPathCloseが正常に設定されている場合にのみ有効です。 詳細な情報はGameCreateGameCloseWebhookをご参照ください。
  • AsyncJoin
    このオプションは、IsPersistenttrueに設定されている場合にのみ有効です。 デフォルトではtrueに設定されており、サーバー上の名前でルームを見つけることができないjoinオペレーションがWebhookとしてWebサービスに転送されます。 この動作を非有効化するには、falseに設定してください。 詳細はこちらを参照してください。

クエリ文字列の処理

クエリ文字列パラメータはベースURLに含めることができます。 使用する場合は、以下の事柄を理解しておいてください。

  • クエリ文字列はそのまま使用されます。URLエンコードは実行されません。重複キーは実行されません。
  • クエリ文字列パラメータ内でURLタグを使用できます。
  • クエリ文字列はパス設定に追加できません。

例:

  • 設定:

    • ベースURL:

      Unknown

      https://myawesomegame.com/chat/webhooks?clientver={AppVersion}&key=&keyA=valueA&keyA=valueB&keyB=valueB&=value
      
    • PathCreate: create
    • PathClose: close
  • 生じるURL:

    • PathCreate:

      Unknown

      https://myawesomegame.com/realtime/webhooks/create?clientver=1.0&key=&keyA=valueA&keyA=valueB&keyB=valueB&=value
      
    • PathClose:

      Unknown

      https://myawesomegame.com/realtime/webhooks/close?clientver=1.1&key=&keyA=valueA&keyA=valueB&keyB=valueB&=value
      

HTTP Headers Considerations

カスタムHTTPヘッダーの使用にあたり、いくつかの留意事項があります:

  • CustomHttpHeaders設定キーの値は、文字列に変更された、文字列以外を含まないプロパティのJSONオブジェクトである必要があります。JSONオブジェクトのプロパティ名は、HTTPリクエストヘッダフィールド名として使用され、プロパティの値はリクエストヘッダーのそれぞれの値として使用されます。 例:

    • CustomHttpHeaders 値:

      Unknown

      {'X-Secret': 'YWxhZGRpbjpvcGVuc2VzYW1l', 'X-Origin': 'Photon'}
      
    • Webhooks HTTP リクエストヘッダー:

      Unknown

      X-Secret: YWxhZGRpbjpvcGVuc2VzYW1l
      X-Origin: Photon
      
  • カスタムHTTPヘッダーフィールド名は大文字と小文字を区別します。

  • DateIf-Modified-Sinceに対応しているフォーマットはこちら

  • Content-Typeは、Webhookプラグインによりapplication/jsonに設定されるため、使用できません。

  • 次のHTTPヘッダーは制限されており、"CustomHttpHeaders"設定値から設定された場合、無視されます。

    • Connection
    • Content-Length
    • Host
    • Range
    • Proxy-Connection

ターンキーソリューション

Microsoft AzureとHerokuで利用可能な最新のターンキーインストレーションについては、弊社のgithubページを参照してください。

URLタグ

ダッシュボードからwebhookまたはWebRpcのベースURLを設定する場合、必要に応じて、クエリ文字列の一部として1つ以上の動的変数 を設定することができます。 これらの変数は、リクエストを送信する前に、バックエンドでそれぞれの値に置き換えられます。

それぞれのアプリケーションのユーザー・セグメントを個別に処理したい場合は、URLのタグを使用します。 Photonは、次のURLのタグに対応しています:

  • {AppVersion} クライアントによって設定されたアプリケーションのバージョンを渡します。
  • {AppId} アプリケーションのIDを渡します。
  • {Region} トリガークライアントが接続されているクラウドリージョンのトークンを渡します。例:"eu"
  • {Cloud} は、トリガークライアントが接続されているクラウドの名前を渡します。例:「public」または「enigmaticenterprise」

URLタグの例

  1. https://{Region}.mydomain.com/{AppId}?version={AppVersion}&cloud={Cloud} 例:パラメータとして渡される異なるホスト、バージョン、およびクラウドに各リージョンをルート。
  2. https://mydomain.com/{Cloud}/{Region}/{AppId}/{AppVersion} 構造化されたURIとしてすべてのタグを渡します。

共通のクライテリア

すべてのPhotonのWebhookは、POSTするベースURL、Webサーバーで起こり得るエラーを返す能力、それぞれに送信されるベースラインデータを共有しています。

すべてのWebhookに共通の引数

AppId: ゲームクライアントから設定されるアプリケーションのAppID。ダッシュボードで確認できます。

AppVersion: ゲームクライアントから設定されるアプリケーションのバージョン。

Region: ゲームクライアントが接続し、該当のルームが属するリージョンを持ちます。

GameId: ルームのIDまたは名前。

Type: Webhookのタイプ。 PathEvent webhookでは常に"Event"です。PathJoin webhookでは常に"Join"です。その他のすべてのwebhookでは複数の値を持つことが可能です。

PathClose以外のすべてのWebhookに共通の引数

ActorNr: hookをトリガーするアクターの数。

UserId: hookをトリガーするアクターのUserId。

NickName: クライアントSDKから設定されたhookをトリガーするアクターの名前。

戻り値

想定されるレスポンス

Webhookを送る際、Photon Serverはほとんどの場合、JSONオブジェクトのResultCodeプロパティが0に設定されたレスポンスのみを期待します。 ResultCodeがゼロならば、Webhookリクエストが受信され、Webサーバー上で正常に処理されていることを確認できます。

Webhookのコールに対して、ゼロ以外のResultCodeを伴うリターンオブジェクトの場合にはどのようなWebhookのコールでも、失敗と認識されます。 HasErrorInfoがtrueに設定されている場合、まだルームに参加しているクライアントにErrorInfoイベントが送信されます。 PathCreateの場合を除き、このような状況でもサーバーは通常の処理を続行します。イベントにはParameterCode.Infoも含まれます。 詳細はSDKのAPIドキュメントを参照してください

Photon Cloud によってすでに閉じられてメモリーから削除されたルームにプレイヤーが再び参加しようとした場合にのみ、Photonは追加のリクエストをします。 詳細は下記のPathCreate項目をご確認ください。

ベストプラクティス

各Webhookに必要な引数は常に確認してください。 必要な引数が不足の場合を想定して、人間が読解可能なエラーコードを戻すように設計してください。 Webhookのリターンオブジェクトの推奨フォーマットは{ "ResultCode" : x, "Message" : "xxx" }です。

戻り値を処理するおすすめの方法は、Webhookのバックエンドロジックにヘルパールーチンを実装することです。 以下に、Webhookのリターンオブジェクトの例をいくつか羅列します。

  • 成功した場合のデフォルトのリターンオブジェクト

    { "ResultCode" : 0 }
    { "ResultCode" : 0, "Message" : "OK" }

  • Photon側またはWebサーバー上でのプロトコルレベルのエラー

    { "ResultCode" : 1, "Message" : "Missing Webhook Argument: <argument name>." }

  • アプリケーション固有のエラー

    { "ResultCode" : 2, "Message" : "Game with GameId=<gameId> already exists." }
    { "ResultCode" : 3, "Message" : "Could not load the State, Reason=<reason>." }

パスの詳細

PathCreate

JoinOrCreateRoom呼び出しの結果としてルームが作成された場合は、以下の場合のみ"PathCreate" webhookがトリガーされます。
  • "IsPersistent"が"true"に設定されている。
  • "PathCreate"が設定されている。
  • "PathClose"が設定されている。
その他の場合は、ルームは作成されますがwebhookは引き起こされません。

このWebhookは、サーバーレベルでルームが作成されるたびにトリガーされます。 OpCreateRoomを使用してルームが作成されると、このWebhookはType引数をCreateに設定します。 ルーム作成時に使用されるほとんどのRoomOptionsTypedLobbyは、CreateOptionsとして送信されます。 ActorNrの値は1で、アクターはPathJoinWebhookを除くことなく、自動的にルームに参加します。

アクターが、以前作成されてPhoton Cloudから削除されたルームに参加、または再び参加しようとすると、TypeLoadに設定されます。 また、Webサーバーは同じルームの直列化されたStateを返します。 バックエンドのロジックは、以前に保存され直列化されたルームステートのバージョンを引き出す必要があります。

ステートが見つかった場合、Webサーバー側は{ "State" : state, "ResultCode" : 0 }のようなJSONオブジェクトを返すべきです。 何らかの理由でステートが見つからない場合、Webサービス側はCreateIfNotExistsの値を確認して、新しいステートでのルーム作成を許可または却下すべきです。 CreateIfNotExistsがtrueの場合、空のルームステートを返し(たとえば{ "State" : "", "ResultCode" : 0 })、クライアント側のルームオプションの設定に従ってルームの作成を許可することができます。 値がfalseの場合には、Webサーバーがステートの読み込みに失敗したことを0以外のResultCodeで返し、Photon Cloudに通知するように設計してください。 人間が読解可能な、原因とエラーメッセージを追加するよう検討してください。

"IsPersistent"がtrueに設定され、また"PathCreate"と"PathClose"がともに設定されると、以下の場合ではルーム作成、非同期参加または再参加は失敗します:
  • "PathCreate"は到達できず、もしくはHTTPエラーを返した。
  • "PathCreate" は0以外のResultCodeを返した。
  • Photon Serverは受信したルームステートの分析または設定に失敗した。

AsyncJoinオプション

Photonアプリケーションは、ゲーム作成後に数時間経過してから招待を承認するなどの非同期オペレーションをサポートしているため、フレンドのプレイヤー同士が一緒にプレイしやすくなっています。IsPersistentAsyncJoinがともに有効化されている場合、 Photonサーバーメモリにルームが見つからないとルーム参加オペレーションはPathCreate (Type="Load") Webhookをトリガーします。 この仕様は、そのルームが以前作成され保存されたことを想定して、Webサービスからルームステートをローディングすることを目的としています。

IsPersistenttrueの場合、AsyncJoinはデフォルトで有効化されます。 AsyncJoinを非有効化するには、Webhook設定にない場合にキーを追加し、その値をfalseに設定します。

以下の表はIsPersistentが有効化された場合に、Type="Load"をともなうPathCreate Webhookをトリガーするすべてのクライアントオペレーションを記載しています。

クライアントオペレーション JoinMode AsyncJoin = false AsyncJoin = true AsyncJoin = N/A
OpJoinRoom デフォルト(参加)
OpRejoinRoom RejoinOnly
OpJoinOrCreateRoom CreateIfNotExists

特定の引数

PathCreate, Type "Create"

CreateOptions: ルームを作成する際に使用されるオプションです。 このオプションには、使用されるTypedLobbyの詳細など、 クライアントが設定するRoomOptionsクラスからの情報が含まれます。 全てのプロパティはStateにそのままコピーされるので、後でStateから取得することができます。

以下の表は、CreateOptionsRoomOptionsの比較を示しています。

プロパティまたはフィールド CreateOptions RoomOptions Notes
IsVisible 後でルームのステートから取得可能
IsOpen 後でルームのステートから取得可能
MaxPlayers
PlayerTtl
EmptyRoomTtl
CheckUserOnJoin プレイヤーごとに固有のIDがある場合、これをtrueに設定する必要があります。
SuppressRoomEvents trueに設定されている場合、参加と退室どちらの場合にもルームイベントは送信されません。          デフォルトはfalseで、送信されます。        
DeleteCacheOnLeave これはRoomOptionsではCleanupCacheOnLeaveと呼ばれます。
LobbyType ルームのロビーの種類で、ゲームクライアントによってTypedLobby.Typeで設定されます。 詳細はSDKのAPIドキュメントをご確認ください。
LobbyId ルームのロビーの名前で、ゲームクライアントによってTypedLobby.Nameで設定されます。 詳細はSDKのAPIドキュメントをご確認ください。
CustomProperties パブリックであるべき、ルームの初期カスタムプロパティのみが含まれています。すなわち、ロビーで表示されます。
CustomRoomProperties ルームのすべての初期カスタムプロパティが含まれています。
CustomRoomPropertiesForLobby パブリックであるべき、ルームのカスタムプロパティのキーが含まれています。すなわち、ロビーで表示されます。
PublishUserId プレイヤーのUserIDが「パブリッシュされた」場合に定義します。
         後でルームのステートから取得可能。
         詳細は、こちらを参照してください。

PathCreate, Type "Load"

CreateIfNotExists: ルームのステートがWebサービスに見つからない場合に、新しいルームを作成する必要があるか表示するために使用されるフラグです。

CreateOptions以外にある、ルームのStateのプロパティ:

  • ActorCounter: 最後に参加したアクターのActorNr。
  • ActorList: ルーム内に存在する各アクター(アクティブまたはインアクティブ)に関する情報エントリーの配列。 各エントリーには以下のプロパティがあります: :
    • ActorNr: ルーム内のアクターの番号。
    • UserId: アクターのUserID 。
    • NickName: アクターのNickName。
    • IsActive: アクターがルームに参加したかどうかを示します。これは、 PathCloseState引数では送信されません。
    • DeactivationTime: ルーム退出イベントのタイムスタンプ。 PathCloseState引数でのみ送信されます。.
    • Binary*: Base64エンコーディングされたアクタープロパティ。
    • DEBUG_BINARY**: アクタープロパティの読み取り可能な形式。
  • Slice: キャッシュスライス・インデックス。
  • Binary *: Base64エンコーディングされたルームプロパティとキャッシュイベント。
  • DebugInfo **: バイナリデータの読み取り可能な形式。
    • DEBUG_PROPERTIES_18**: ルームプロパティの読み取り可能な形式。
    • DEBUG_EVENTS_19**: キャッシュされたイベントの読み取り可能な形式。
    • DEBUG_GROUPS_20**: ンタレストグループの読み取り可能な形式。
  • ExpectedUsers: ルームに参加予定のプレイヤーのUserIDの配列。詳細はスロット予約を参照してください。

* : Photonが使用するプロトコルの特性により、Binaryプロパティが存在します。 **: 本番環境のアプリケーションでは、Debugプロパティを非有効化する必要があります。これらのプロパティはデバッグのみに使用してください。

サンプルコール

JSON

{
    "ActorNr": 1,
    "AppVersion": "client-x.y.z",
    "AppId": "00000000-0000-0000-0000-000000000000",
    "CreateOptions": {
        "MaxPlayers": 4,
        "LobbyId": null,
        "LobbyType": 0,
        "CustomProperties": {
            "lobby3Key": "lobby3Val",
            "lobby4Key": "lobby4Val"
        },
        "EmptyRoomTTL": 0,
        "PlayerTTL": 2147483647,
        "CheckUserOnJoin": true,
        "DeleteCacheOnLeave": false,
        "SuppressRoomEvents": false
    },
    "GameId": "MyRoom",
    "Region": "EU",
    "Type": "Create",
    "UserId": "MyUserId1",
    "NickName": "MyPlayer1"
}

PathJoin

JoinOrCreateRoomメソッドを呼ぶ際、以下の場合にのみ"PathJoin"webhookがトリガーされます:
  • 「IsPersistent」が「true」に設定された。
  • 「PathCreate」が設定された。
  • 「PathClose」が設定された。

Photon Cloud から削除されていないルームにアクターが参加または再参加した場合に、このWebhookが送信されます。
Type引数は Joinに設定されます。

特定の引数

PathJoinには追加の引数がありません。

サンプルコール

JSON

{
    "ActorNr": 2,
    "AppVersion": "client-x.y.z",
    "AppId": "00000000-0000-0000-0000-000000000000",
    "GameId": "MyRoom",
    "Region": "EU",
    "Type": "Join",
    "UserId": "MyUserId0",
    "NickName": "MyPlayer0"
}

PathGameProperties

HttpForwardWebフラグが設定され、正しい負荷メソッドを使用している場合、ユーザーがルームまたはプレイヤーのカスタムプロパティを設定すると、毎回このWebhookがクライアント側から送信されます。 このwebhookとともに送信されたType引数は、Game または Actorに設定されます。

特定の引数

Properties: クライアントSDKから送信される、更新された一連のプロパティ。
State: a serialized snapshot of the room's full state. ルームの完全なステートの直列化されたスナップショット。 これはOpSetCustomPropertiesを呼ぶ際に「IsPersistent」設定がtrueに設定され、SendStateウェブフラグが設定されている場合にのみ送信されます。 AuthCookie: 暗号化されたオブジェクトで、クライアントには見えません。カスタム認証が成功した際に、オプションで返されます。 OpSetCustomPropertiesを呼ぶ際に、SendAuthCookieフラグが設定されている場合にのみ送信されます。

PathGameProperties, Type="Actor"
TargetActor: プロパティがアップデートされたアクターの数。

サンプルコール

JSON

{
    "ActorNr": 1,
    "AppVersion": "client-x.y.z",
    "AppId": "00000000-0000-0000-0000-000000000000",
    "Properties": {
        "turn": 1,
        "lobby3Key": "test1a",
        "lobby4Key": "test1b"
    },
    "GameId": "MyRoom",
    "Region": "EU",
    "State": {
        "ActorCounter": 2,
        "ActorList": [
            {
                "ActorNr": 1,
                "UserId": "MyUserId1",
                "NickName": "MyPlayer1",
                "IsActive": true,
                "Binary": "RGIAAAEBRAAAAAJzAAlz...",
                "DEBUG_BINARY": {
                    "1": {
                        "255": "MyPlayer1",
                        "player_id": "12345"
                    }
                }
            },
            {
                "ActorNr": 2,
                "UserId": "MyUserId0",
                "NickName": "MyPlayer0",
                "IsActive": true,
                "Binary": "RGIAAEBRAAAAAFi/3M15...",
                "DEBUG_BINARY": {
                    "1": {
                        "255": "MyPlayer0"
                    }
                }
            }
        ],
        "Binary": {
            "18": "RAAAAAdzAAhwcm9wMUtl..."
        },
        "CheckUserOnJoin": true,
        "CustomProperties": {
            "lobby4Key": "test1b",
            "lobby3Key": "test1a"
        },
        "DeleteCacheOnLeave": false,
        "EmptyRoomTTL": 0,
        "IsOpen": true,
        "IsVisible": true,
        "LobbyType": 0,
        "LobbyProperties": [
            "lobby3Key",
            "lobby4Key"
        ],
        "MaxPlayers": 4,
        "PlayerTTL": 2147483647,
        "SuppressRoomEvents": false,
        "Slice": 0,
        "DebugInfo": {
            "DEBUG_PROPERTIES_18": {
                "250": [
                    "lobby3Key",
                    "lobby4Key"
                ],
                "prop1Key": "prop1Val",
                "prop2Key": "prop2Val",
                "lobby4Key": "test1b",
                "lobby3Key": "test1a",
                "map_name": "mymap",
                "turn": 1
            }
        }
    },
    "Type": "Game",
    "UserId": "MyUserId1",
    "NickName": "MyPlayer1"
}

PathEvent

HttpForwardフラグが設定され、正しい負荷メソッドを使用している場合、ユーザーがクライアント側からカスタムイベントを発生させると毎回送信されます。 カスタムイベントコードとイベントデータは、Webhookと送信されます。

特定の引数

EvCode: カスタムイベントコード Data: ライアントSDKから送信されるカスタムイベントデータ State: ルームの完全なステートの直列化されたスナップショット。 OpRaiseEvent を呼ぶ際にSendStateWebフラグが設定され、"IsPersistent"がtrueに設定されている場合にのみ送信されます。 AuthCookie: 暗号化されたオブジェクトで、クライアントには見えません。カスタム認証が成功した際に、オプションで返されます。 OpRaiseEventを呼ぶ際に、SendAuthCookieフラグが設定されている場合にのみ送信されます。

サンプルコール

JSON

{
    "ActorNr": 3,
    "AppVersion": "client-x.y.z",
    "AppId": "00000000-0000-0000-0000-000000000000",
    "Data": "data",
    "GameId": "MyRoom",
    "Region": "EU",
    "State": {
        "ActorCounter": 3,
        "ActorList": [
            {
                "ActorNr": 1,
                "UserId": "MyUserId1",
                "NickName": "MyPlayer1",
                "Binary": "RGIAAAEBRAAAAAJzAAlw...",
                "DEBUG_BINARY": {
                    "1": {
                        "255": "MyPlayer1",
                        "player_id": "12345"
                    }
                }
            },
            {
                "ActorNr": 3,
                "UserId": "MyUserId0",
                "NickName": "MyPlayer0",
                "IsActive": true,
                "Binary": "RGIAAAEBRAAAAAFi/3MAC...",
                "DEBUG_BINARY": {
                    "1": {
                        "255": "MyPlayer0"
                    }
                }
            }
        ],
        "Binary": {
            "18": "RAAAAAdzAAhwcm9wMUtl...",
            "19": "RGl6AAEAAAAAAAN6AANp..."
        },
        "CheckUserOnJoin": true,
        "CustomProperties": {
            "lobby4Key": "test1b",
            "lobby3Key": "test1a"
        },
        "DeleteCacheOnLeave": false,
        "EmptyRoomTTL": 0,
        "IsOpen": true,
        "IsVisible": true,
        "LobbyType": 0,
        "LobbyProperties": [
            "lobby3Key",
            "lobby4Key"
        ],
        "MaxPlayers": 4,
        "PlayerTTL": 2147483647,
        "SuppressRoomEvents": false,
        "Slice": 0,
        "DebugInfo": {
            "DEBUG_PROPERTIES_18": {
                "250": [
                    "lobby3Key",
                    "lobby4Key"
                ],
                "prop1Key": "prop1Val",
                "prop2Key": "prop2Val",
                "lobby4Key": "test1b",
                "lobby3Key": "test1a",
                "map_name": "mymap",
                "turn": 1
            },
            "DEBUG_EVENTS_19": {
                "0": [
                    [
                        3,
                        0,
                        "data"
                    ],
                    [
                        3,
                        0,
                        "data"
                    ],
                    [
                        3,
                        0,
                        "data"
                    ]
                ]
            }
        }
    },
    "Type": "Event",
    "UserId": "MyUserId0",
    "NickName": "MyPlayer0",
    "EvCode": 0
}

PathLeave

このhookは、アクターがPhotonゲームサーバーから切断される度にトリガーされます。 切断にはいくつかの原因が考えられます。 このWebhookは、人間が読解可能な形式でType、そして理由のコードでReasonを表示します。

特定の引数

Type: 人間が読解可能な形式で理由を表示し、以下のいずれかの値となる可能性があります:

  • ClientDisconnect: クライアントがOpLeaveRoom()またはDisconnect()を呼んだことを示します。
  • ClientTimeoutDisconnect: クライアントがサーバーをタイムアウトしたことを示します。 UDP/ENETを使用している場合のみ有効です。 これは、UDP / ENETを使用する場合にのみ有効です。
  • ManagedDisconnect: クライアントの処理速度が遅すぎて、データ送信を処理できないことを示します。
  • ServerDisconnect: データ破損が原因と考えられる低レベルのプロトコルエラーを示します。
  • TimeoutDisconnect: クライアントがサーバーを タイムアウト したことを示します。 詳細は切断の調査についてのドキュメントを参照してください。
  • LeaveRequest: クライアントがOpLeaveRoom() OpLeaveRoom(false)を呼んで明確にルームを放棄したことを示します。
  • PlayerTtlTimedOut: インアクティブユーザーが タイムアウト したことを示し、そのアクターに対してルームのPlayerTtLが失効したことを意味します。 詳細は、お使いのSDKのAPIドキュメントを参照してください。
  • PeerLastTouchTimedOut: アクターがPhoton Serverに5分間以上 なにも 送信しなかったという、非常に稀な状況を示します。 通常、ピアはそれより前に timeout しますが、Photonは接続しているすべてのピアの、サーバーとの直近の交信(LastTouchと呼びます)の タイムスタンプ を5分ごとに確認します。
  • PluginRequest: アクターがActorListからプラグインによって削除されたことを示します。
  • PluginFailedJoin: Webhook実装によるPhoton Cloud内の内部エラーを示します。

IsInactive: ルームを退室する前のアクターのステートを示します。trueの場合、アクターはゲームに再参加できます。falseの場合には、アクターはActorListから削除され、今後そのゲームに再参加することはできません。

Reason: 理由のコード

以下の表では、それぞれのTypeとそのコードを記載し、どのようにWebhookが作成されるのか、またルーム内のプレイヤーがどのような影響を受けるかを説明します。

ルーム作成時にRoomOptions.PlayerTTLを0に設定した場合

RoomOptions.PlayerTTL == 0であるルームのアクターはインアクティブな状態にはなれないので、退室するとすぐにActorListから削除されます。 設計上、ルームに少なくとも1人以上のインアクティブアクターがいる場合のみルームステートを保存する必要があるため、IsPersistentオプションは無視されます。

イベントがPathLeave webhookをトリガーすると、該当するアクターはルームから削除されますから、 アクターがアクティブかどうか確認のためだけにはPathLeaveWebhookを使用しないでください。 しかもこの状態ではOpLeaveRoom(true))は使用できなくなり、PathLeaveの PlayerTtlTimedOutタイプも発生しません。

タイプ 理由 トリガー Inactive
ClientDisconnect 0 Disconnect()へのコール false
ClientTimeoutDisconnect 1 Photonサーバーからのコール false
ManagedDisconnect 2 Photonサーバーからのコール false
ServerDisconnect 3 Photonサーバーからのコール false
TimeoutDisconnect 4 Photonサーバーからのコール false
LeaveRequest 101 OpLeaveRoom()へのコール false
PlayerTtlTimedOut 102 N/A N/A
PeerLastTouchTimedout 103 Photon Serverからのコール false
PluginRequest 104 プラグインからのコール false
PluginFailedJoin 105 Photon Serverからのコール false
ルーム作成時にRoomOptions.PlayerTTL != 0を設定した場合:
タイプ 理由 トリガー IsInactive
ClientDisconnect 0 Disconnect()へのコール true
ClientTimeoutDisconnect 1 Photonサーバーからのコール true
ManagedDisconnect 2 Photonサーバーからのコール true
ServerDisconnect 3 Photonサーバーからのコール true
TimeoutDisconnect 4 Photonサーバーからのコール true
LeaveRequest 101 OpLeaveRoom()へのコール false
PlayerTtlTimedOut 102 Photonサーバーからのコール false
PeerLastTouchTimedout 103 Photonサーバーからのコール false
PluginRequest 104 プラグインからのコール false
PluginFailedJoin 105 Photonサーバーからのコール false

サンプルコール

JSON

{
    "ActorNr": 1,
    "AppVersion": "client-x.y.z",
    "AppId": "00000000-0000-0000-0000-000000000000",
    "GameId": "MyRoom",
    "IsInactive": true,
    "Reason": "0",
    "Region": "EU",
    "Type": "ClientDisconnect",
    "UserId": "MyUserId1",
    "NickName": "MyPlayer1"
}

PathClose

このhookはPhoton Cloudのメモリから ルームインスタンスを削除する直前に送信されます。 EmptyRoomTTLが期限切れの場合にのみ発生します。 ルーム作成時にEmptyRoomTTLが設定された数値により、ルームが空になってからタイマーが動作してカウントダウンし始めます。 最後のアクティブなアクターがルームを退室した際に、ルームは空になったと判断されます。

IsPersistentがtrueに設定されると、Photon Cloudはルームの直列化された スナップショット であるStateを送信します。これには ルームのプロパティのほか、アクターやキャッシュ済みイベントの情報が含まれます。 この場合、WebhookのTypeにはSave値が設定されます。

IsPersistentがデフォルトのfalseに設定された場合、TypeはCloseとなりState は送信されず、ルームは消滅します。

特定の引数

ActorCount: インアクティブなアクターの数。0の場合、Typeは"Close"にする必要があります。

PathClose、Type"Save"

State: ルームの完全なステートの直列化されたスナップショット。

サンプルコール

JSON

{
    "ActorCount": 2,
    "AppVersion": "client-x.y.z",
    "AppId": "00000000-0000-0000-0000-000000000000",
    "GameId": "MyRoom",
    "Region": "EU",
    "State": {
        "ActorCounter": 3,
        "ActorList": [
            {
                "ActorNr": 1,
                "UserId": "MyUserId1",
                "NickName": "MyPlayer1",
                "Binary": "RGIAAAEBRAAAAAJzAAlw...",
                "DEBUG_BINARY": {
                    "1": {
                        "255": "MyPlayer1",
                        "player_id": "12345"
                    }
                }
            },
            {
                "ActorNr": 3,
                "UserId": "MyUserId0",
                "NickName": "MyPlayer0",
                "Binary": "RGIAAAEBRAAAAAFi/3MA...",
                "DEBUG_BINARY": {
                    "1": {
                        "255": "MyPlayer0"
                    }
                }
            }
        ],
        "Binary": {
            "18": "RAAAAAdzAAhwcm9wMUtl...",
            "19": "RGl6AAEAAAAAAAN6AANp..."
        },
        "CheckUserOnJoin": true,
        "CustomProperties": {
            "lobby4Key": "test1b",
            "lobby3Key": "test1a"
        },
        "DeleteCacheOnLeave": false,
        "EmptyRoomTTL": 0,
        "IsOpen": true,
        "IsVisible": true,
        "LobbyType": 0,
        "LobbyProperties": [
            "lobby3Key",
            "lobby4Key"
        ],
        "MaxPlayers": 4,
        "PlayerTTL": 2147483647,
        "SuppressRoomEvents": false,
        "Slice": 0,
        "DebugInfo": {
            "DEBUG_PROPERTIES_18": {
                "250": [
                    "lobby3Key",
                    "lobby4Key"
                ],
                "prop1Key": "prop1Val",
                "prop2Key": "prop2Val",
                "lobby4Key": "test1b",
                "lobby3Key": "test1a",
                "map_name": "mymap",
                "turn": 1
            },
            "DEBUG_EVENTS_19": {
                "0": [
                    [
                        3,
                        0,
                        "data"
                    ],
                    [
                        3,
                        0,
                        "data"
                    ],
                    [
                        3,
                        0,
                        "data"
                    ]
                ]
            }
        }
    },
    "Type": "Save"
}

ルームステートの除去

ルームステートのサイズが懸念事項である場合には、サイズを縮小し、データを失わずに済む方法があります。 Webサービスでルームステートを保存する際、以下の方法でサイズを縮小できます:

  1. ルームのローディング時にルームステートの再構築に使用されない、デバッグを目的に作成された読み取り専用のいくつかのフィールドを削除。 該当するフィールドは: CustomPropertiesDebugInfo、またActorList内の各アクターのすべてのDEBUG_BINARYNickNameです。 これらのフィールドは、ルームステートを非直列化する際に無視されるため、削除しても問題ありません。

    以下は、PathCreateで返される完全なルームステートです、Type="Load"Webhook:

    JSON

    {
        "ResultCode": 0,
        "Message": "Room State successfully loaded",
        "State": {
            "ActorCounter": 3,
            "ActorList": [
                {
                    "ActorNr": 1,
                    "UserId": "MyUserId1",
                    "NickName": "MyPlayer1",
                    "Binary": "RGIAAAEBRAAAAAJzAAlw...",
                    "DEBUG_BINARY": {
                        "1": {
                            "255": "MyPlayer1",
                            "player_id": "12345"
                        }
                    }
                },
                {
                    "ActorNr": 3,
                    "UserId": "MyUserId0",
                    "NickName": "MyPlayer0",
                    "Binary": "RGIAAAEBRAAAAAFi/3MA...",
                    "DEBUG_BINARY": {
                        "1": {
                            "255": "MyPlayer0"
                        }
                    }
                }
            ],
            "Binary": {
                "18": "RAAAAAdzAAhwcm9wMUtl...",
                "19": "RGl6AAEAAAAAAAN6AANp..."
            },
            "CheckUserOnJoin": true,
            "CustomProperties": {
                "lobby4Key": "test1b",
                "lobby3Key": "test1a"
            },
            "DeleteCacheOnLeave": false,
            "EmptyRoomTTL": 0,
            "IsOpen": true,
            "IsVisible": true,
            "LobbyType": 0,
            "LobbyProperties": [
                "lobby3Key",
                "lobby4Key"
            ],
            "MaxPlayers": 4,
            "PlayerTTL": 2147483647,
            "SuppressRoomEvents": false,
            "Slice": 0,
            "DebugInfo": {
                "DEBUG_PROPERTIES_18": {
                    "250": [
                        "lobby3Key",
                        "lobby4Key"
                    ],
                    "prop1Key": "prop1Val",
                    "prop2Key": "prop2Val",
                    "lobby4Key": "test1b",
                    "lobby3Key": "test1a",
                    "map_name": "mymap",
                    "turn": 1
                },
                "DEBUG_EVENTS_19": {
                    "0": [
                        [
                            3,
                            0,
                            "data"
                        ],
                        [
                            3,
                            0,
                            "data"
                        ],
                        [
                            3,
                            0,
                            "data"
                        ]
                    ]
                }
            }
        }
    }
    

    以下は、同じWebhookで返されるルームステートの、除去されたバージョンです:

    JSON

    {
        "ResultCode": 0,
        "Message": "Room State successfully loaded",
        "State": {
            "ActorCounter": 3,
            "ActorList": [
                {
                    "ActorNr": 1,
                    "UserId": "MyUserId1",
                    "Binary": "RGIAAAEBRAAAAAJzAAlw..."
                },
                {
                    "ActorNr": 3,
                    "UserId": "MyUserId0",
                    "Binary": "RGIAAAEBRAAAAAFi/3MA..."
                }
            ],
            "Binary": {
                "18": "RAAAAAdzAAhwcm9wMUtl...",
                "19": "RGl6AAEAAAAAAAN6AANp..."
            },
            "CheckUserOnJoin": true,
            "DeleteCacheOnLeave": false,
            "EmptyRoomTTL": 0,
            "IsOpen": true,
            "IsVisible": true,
            "LobbyType": 0,
            "LobbyProperties": [
                "lobby3Key",
                "lobby4Key"
            ],
            "MaxPlayers": 4,
            "PlayerTTL": 2147483647,
            "SuppressRoomEvents": false,
            "Slice": 0
        }
    }
    
  2. アプリケーションロジックで固定値とみなされ、ルームのライフタイムを通じて変更の必要がない、またはルームのローディング時にPhoton Serverにステートを返す前にコードで再設定できるいくつかのフィールドを除去。 これらのフィールドは、Photonサーバーにステートを返す前に当初の値を追加しなければなりません。当初の値を追加しないと、ステートが破損する可能性があります。

    該当するフィールドは以下のとおりです:

    • ActorCounter
    • CheckUserOnJoin
    • DeleteCacheOnLeave
    • EmptyRoomTTL
    • IsOpen
    • IsVisible
    • MaxPlayers
    • LobbyId
    • LobbyType
    • LobbyProperties
    • PlayerTTL
    • SuppressRoomEvents
    • Slice

Webhookを保護する

HTTPSと最新のTLSバージョンの使用だけでなく、カスタムHTTPリクエストヘッダクエリ文字列パラメータを使用してwebhookセキュリティを強化できます。 受信するHTTPリクエストがPhoton Serverで生成されいることがわかるように、Photonのダッシュボードで1つもしくは複数の「秘密」(「トークン」、「キー」など)を設定します。

Back to top