Webhooks
Photon CloudでWebhookを使用するとアプリケーションを拡張でき、ゲームへのプレイヤーの再参加や、プレイヤーおよびゲームデータの保持が可能になります。
Photon WebhookはPhoton Cloudによって特定のURLに送信されるイベント駆動型のHTTP POSTリクエストです。
それぞれのPhoton Webhookは、それぞれ固有のトリガー、データ、目的地へのパスによって定義されます。
セットアップ
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が正常に設定されている場合にのみ有効です。
詳細な情報はGameCreate と GameCloseWebhookをご参照ください。 - AsyncJoin
このオプションは、IsPersistent がtrue
に設定されている場合にのみ有効です。
デフォルトではtrue
に設定されており、サーバー上の名前でルームを見つけることができないjoinオペレーションがWebhookとしてWebサービスに転送されます。
この動作を非有効化するには、false
に設定してください。
詳細はこちらを参照してください。
クエリ文字列の処理
クエリ文字列パラメータはベースURLに含めることができます。
使用する場合は、以下の事柄を理解しておいてください。
- クエリ文字列はそのまま使用されます。URLエンコードは実行されません。重複キーは実行されません。
- クエリ文字列パラメータ内でURLタグを使用できます。
- クエリ文字列はパス設定に追加できません。
例:
設定:
- ベースURL:
https://myawesomegame.com/chat/webhooks?clientver={AppVersion}&key=&keyA=valueA&keyA=valueB&keyB=valueB&=value
- PathCreate:
create
- PathClose:
close
- ベースURL:
生じるURL:
- PathCreate:
https://myawesomegame.com/realtime/webhooks/create?clientver=1.0&key=&keyA=valueA&keyA=valueB&keyB=valueB&=value
- PathClose:
https://myawesomegame.com/realtime/webhooks/close?clientver=1.1&key=&keyA=valueA&keyA=valueB&keyB=valueB&=value
- PathCreate:
HTTP Headers Considerations
カスタムHTTPヘッダーの使用にあたり、いくつかの留意事項があります:
CustomHttpHeaders設定キーの値は、文字列に変更された、文字列以外を含まないプロパティのJSONオブジェクトである必要があります。JSONオブジェクトのプロパティ名は、HTTPリクエストヘッダフィールド名として使用され、プロパティの値はリクエストヘッダーのそれぞれの値として使用されます。
例:- CustomHttpHeaders 値:
{'X-Secret': 'YWxhZGRpbjpvcGVuc2VzYW1l', 'X-Origin': 'Photon'}
- Webhooks HTTP リクエストヘッダー:
X-Secret: YWxhZGRpbjpvcGVuc2VzYW1l X-Origin: Photon
- CustomHttpHeaders 値:
カスタムHTTPヘッダーフィールド名は大文字と小文字を区別します。
Date
とIf-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タグの例
https://{Region}.mydomain.com/{AppId}?version={AppVersion}&cloud={Cloud}
例:パラメータとして渡される異なるホスト、バージョン、およびクラウドに各リージョンをルート。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は、サーバーレベルでルームが作成されるたびにトリガーされます。
OpCreateRoomを使用してルームが作成されると、このWebhookはType
引数をCreate
に設定します。
ルーム作成時に使用されるほとんどのRoomOptions
とTypedLobby
は、CreateOptions
として送信されます。
ActorNr
の値は1で、アクターはPathJoinWebhookを除くことなく、自動的にルームに参加します。
アクターが、以前作成されてPhoton Cloudから削除されたルームに参加、または再び参加しようとすると、Type
はLoad
に設定されます。
また、Webサーバーは同じルームの直列化されたState
を返します。
バックエンドのロジックは、以前に保存され直列化されたルームステートのバージョンを引き出す必要があります。
ステートが見つかった場合、Webサーバー側は{ "State" : state, "ResultCode" : 0 }
のようなJSONオブジェクトを返すべきです。
何らかの理由でステートが見つからない場合、Webサービス側はCreateIfNotExists
の値を確認して、新しいステートでのルーム作成を許可または却下すべきです。
CreateIfNotExists
がtrueの場合、空のルームステートを返し(たとえば{ "State" : "", "ResultCode" : 0 }
)、クライアント側のルームオプションの設定に従ってルームの作成を許可することができます。
値がfalseの場合には、Webサーバーがステートの読み込みに失敗したことを0以外のResultCode
で返し、Photon Cloudに通知するように設計してください。
人間が読解可能な、原因とエラーメッセージを追加するよう検討してください。
true
に設定され、また"PathCreate"と"PathClose"がともに設定されると、以下の場合ではルーム作成、非同期参加または再参加は失敗します:
- "PathCreate"は到達できず、もしくはHTTPエラーを返した。
- "PathCreate" は
0
以外のResultCode
を返した。 - Photon Serverは受信したルームステートの分析または設定に失敗した。
AsyncJoinオプション
Photonアプリケーションは、ゲーム作成後に数時間経過してから招待を承認するなどの非同期オペレーションをサポートしているため、フレンドのプレイヤー同士が一緒にプレイしやすくなっています。IsPersistent
とAsyncJoin
がともに有効化されている場合、
Photonサーバーメモリにルームが見つからないとルーム参加オペレーションはPathCreate
(Type="Load"
) Webhookをトリガーします。
この仕様は、そのルームが以前作成され保存されたことを想定して、Webサービスからルームステートをローディングすることを目的としています。
IsPersistent
がtrue
の場合、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
から取得することができます。
以下の表は、CreateOptions
とRoomOptions
の比較を示しています。
プロパティまたはフィールド | 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
: ルーム内に存在する各アクター(アクティブまたはインアクティブ)に関する情報エントリーの配列。
各エントリーには以下のプロパティがあります: :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サービスでルームステートを保存する際、以下の方法でサイズを縮小できます:
ルームのローディング時にルームステートの再構築に使用されない、デバッグを目的に作成された読み取り専用のいくつかのフィールドを削除。
該当するフィールドは:CustomProperties
、DebugInfo
、またActorList
内の各アクターのすべてのDEBUG_BINARY
とNickName
です。
これらのフィールドは、ルームステートを非直列化する際に無視されるため、削除しても問題ありません。以下は、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 } }
アプリケーションロジックで固定値とみなされ、ルームのライフタイムを通じて変更の必要がない、またはルームのローディング時に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つもしくは複数の「秘密」(「トークン」、「キー」など)を設定します。