よくある質問
どのPhoton製品を使用するべきでしょうか?
対象となるゲームやプロジェクトの特性によって異なります。
通常、弊社はFusion または
Quantumの使用を推奨しています。これらは、弊社のもっとも高度なクライアントソリューションです。
概要について、どちらの製品シートにも製品選びのための「Quadrant」が記載されています:
また、Photon CloudとPhoton Serverのどちらを選択すべきかは、こちらを参照ください。
ご不明点はお気軽にお問合せください。
ロードバランシング
Photonのルームでサポートされるプレイヤーの最大数は?
Photonを利用したマルチプレイゲームのほとんどはプレイヤー数が2~16人です。ただし、理論上のルームごとのプレイヤー数/ピアの上限は非常に高く設定されています。
プレイヤー数が32人、または64人で稼働しているPhoton利用ゲームもあり、仮想会議のシナリオでは最大人数が数百人に達する可能性があります。
しかし、1秒あたりの送信メッセージ数(ルームごとのメッセージ数/秒)が多くなりすぎると、クライアントのデータ処理能力によってはパフォーマンスに問題が生じる可能性があります。たとえばターンベースゲームの場合はプレイヤー数が多くなっても全く問題がありませんが、高速アクションゲームでプレイヤー数が32人以上になると、インタレスト管理が必要になるでしょう。
このようにして、すべてのプレイヤーが他の全プレイヤーからのメッセージをもれなく受信できるわけではなくなります。
ルームごとのプレイヤー数は、ゲームルーム内のデータトラフィックを増加させる主な原因です:
このため、弊社はルームごとのメッセージ数/秒を500以下にするよう推奨しています。
Photonはこの上限を強制しませんが、ユーザーの皆様の公正な利用を前提としています。帯域幅使用量を監視することは常に重要である点、また購入プランにもとづき、1CCUあたり3GBのトラフィック範囲内にとどまる点に留意してください。
Photon文字列に上限はありますか?
Photonは文字列を多くの用途で使用します:ルーム名、ロビー名、ユーザーID、ニックネーム、カスタムプロパティキーなどです。
Photonのバイナリプロトコルは、最大32,767文字まで文字列をシリアル化できます。
名前やユーザーIDには36文字で十分でしょう(たとえば、GUIDは36文字です)。
ただし、カスタムプロパティキーの場合には、オーバーヘッドを減らすためにさらに短い文字列を使用しなければなりません。
これは、ロビーに表示されるプロパティの場合に特に重要です。これらのプロパティはルームリストの一部で、ルーム内の数人のクライアントだけでなくロビー内の全員に送信されるためです。
カスタムプロパティ数に上限はありますか?
はい、上限はあります:各ユーザーが設定できるキー値は13,000個までで、ルーム内のキーのサイズは合計で最大500KB未満にする必要があります。
The more Custom Properties are set, the longer the clients take to join a room, as clients receive all of the properties.
カスタムプロパティを多く設定するほど、クライアントがルームに参加するのにかかる時間は長くなります。これは、クライアントはすべてのプロパティを受信するためです。
Photonを使用して、巨大なメッセージを送信できますか?
内容を把握していない限り、Photonを使用して大きなデータ(すなわちファイル)を転送することは推奨しません。
やり取りするデータを最適化してください。やむを得ず非常に大きなメッセージを送信する必要がある場合には、弊社にご連絡ください。
Photon Cloudにはクライアントバッファに対してサーバーサイドの上限があり、5000KBとなっています。
このため状況に応じて、メッセージが以下に該当しないか検討してください:
- Photon Cloud上のクライアントごとのバッファサイズに対して「大きすぎる」> 500KB。クライアントが短時間でこの上限に達する場合、クライアントはサーバーによって切断されます。
- 問題を招く可能性のある分割量が発生するため、UDPで送信するには「大きすぎる」>100KB。
- 複数のUDPパケットに分割して送信する必要があるため、「大きすぎる」 >1.2KB (プロトコルオーバーヘッドを含む)。
定期的かつ頻繁に送信されるメッセージ(1秒間に10回以上)については、1KB以下のサイズを保持するよう推奨します。
メッセージの送信頻度が低い場合(たとえば、マッチの開始時に1回など)には、数KBのサイズでも問題ありません。ただし、10KB以下に保つことを推奨します。
例外的に、20KBや50KBでも問題のない場合があります。
ただし、こうした大きなメッセージは通常、何らかの問題を示しています。修正点がないか確認し、代替策を再検討してください。
どのデータを高信頼、低信頼で送信すべきですか?
まず、信頼性は使用されるプロトコルがUDPの場合のみのオプションである点を認識してください。
TCPには固有の「信頼性」メカニズムがあるため、ここでは説明しません。
高信頼で送信する、とは送信されるものが対象のクライアントに届く点をPhotonが確認する、という意味です。
このため、十分な時間待ってもクライアントが確認応答を得られない場合、クライアントは確認応答を得るまで送信を繰り返すか、再試行回数を超過することになります。
また、高信頼イベントを繰り返すとさらにレイテンシーが発生し、後続のイベントが遅延されます。
信頼性を使用しない例は以下のとおりです:
- リアルタイムゲームでのプレイヤー位置のアップデート
- 音声または動画チャット(ストリーミング)
信頼性を使用する例は以下のとおりです:
- ターンベースゲームでのターンイベント
- めったに変化しないスコアのアップデート
なぜゲームで多くの切断が発生するのでしょうか?
切断には様々な原因が考えられます。
関連する問題を調査するには、以下のドキュメントページを参照してください:
1つのルームの1秒あたりのメッセージの計算方法は?
Photon Serverは、受信/発信メッセージの合計数を毎秒計上し、ルームの合計数(同じマスターサーバー上のルーム合計数)で割っています。
操作リクエスト、操作レスポンス、イベントはすべてメッセージとみなされます。
Photonの操作はオプションの操作レスポンスを返し、イベントをトリガーしない場合もあれば、トリガーする場合もあります。
キャッシュイベントもメッセージとして計上されます。
ルーム内操作で必要なメッセージ数:
操作 | 成功:ベストケース | 成功:平均的なケース | 成功:ワーストケース |
---|---|---|---|
Create | 2 (SuppressRoomEvents=true) |
3 + Join event (SuppressRoomEvents=false, default) |
4 + ErroInfo event (HasErrorInfo=true) |
Join | 2 + k (SuppressRoomEvents=true) + k * cached custom event |
2 + n + k + n * Join event (SuppressRoomEvents=false, default) |
2 + 2 * n + k + n * ErroInfo event (HasErrorInfo=true) |
Leave | 2 (SuppressRoomEvents=true) |
1 + n + (n - 1) * Leave event (SuppressRoomEvents=false, default) |
2 + (n - 1) * 2 + (n - 1) * ErroInfo event (HasErrorInfo=true) |
RaiseEvent | 1 (no operation response) (target: interest group with no subscribers) |
1 + n + n * custom event (target: all/broadcast) |
2 + 2 * n + n * ErroInfo event (HasErrorInfo=true) + Auth event (token refresh) |
SetProperties | 2 Broadcast=false |
2 + n + n * PropertiesChanged event (Broadcast=true, default) |
2 + 2 * n + n * ErrorInfo event (HasErrorInfo=true) |
ユーザーが使用するトラフィックを計算する方法は?
これは難しいトピックです。
まず、いかなる計算も理論上の見積もりであり、現実を反映していない可能性がある点を把握する必要があります。
概念実証をおこなって、実際のデータを収集することをお勧めします。
それとは別に、ここではルーム内の単独ユーザーによって生じるトラフィックを見積もります:
以下を想定してみましょう:
- ルーム内のプレイヤー数はNです。
- 1人のプレイヤーが1秒あたりに送信するメッセージ数はFです(メッセージ送信率の単位はHz)。
- 平均メッセージサイズはX(単位はバイト、ペイロード (P) + プロトコルオーバーヘッド (O))です。
- 平均的なプレイヤーは、そのゲームに1か月あたりH時間を費やします。
ACKを考慮しない場合、接続処理(確立や保持など)が命令や再送信をおこないます。
すると、このゲームでは以下のとおり平均的に1CCUあたりC(単位 バイト/月)を使用します。
C = X * F * N * H * 60 (分/時間) * 60 (秒/分)
切断後すぐにルームに再び参加する方法は?
ルームへの参加中に発生した予期しない切断から回復するために、クライアントはルームへの再接続と再参加を試みることができます。
これを「クイック再入室」と呼びます。
クイック再入室は、次の場合にのみ成功します:
- ルームは同じサーバー上にまだ存在するか、読み込めます:
プレイヤーが退室しても、他のプレイヤーがまだ参加している場合、後者はPhotonサーバー上で生き続けることができます。
プレイヤーが最後に退出し、ルームが空になった場合、EmptyRoomTTLは、プレイヤーが参加または再参加するのを待機している時間です。
EmptyRoomTTLの後、ルームがまだ空で、誰も参加していない場合、Photonサーバーから削除されます。
永続化条件が満たされ、Webhookがセットアップされている場合、ルームの状態を構成済みのWebサービスに保存して、後で読み込むことができます。 - アクターは内部でインアクティブとしてマークされます。同じUserIdを持つアクターがアクターのリスト内に存在しますが、現在ルームに参加していません。
これには、PlayerTTLが0と異なる必要があります。 - インアクティブなアクターのPlayerTTLが期限切れになりませんでした。アクターが戻ってくるオプションを選択してルームを出ると、インアクティブ化タイムスタンプを保存します。
ルームが稼働している限り、インアクティブ化時間からPlayerTTLミリ秒が経過すると、それぞれのアクターがアクターのリストから削除されます。
それ以外の場合、アクターが再入室を試みるときに、再入室の試行時間とインアクティブ化時間のミリ秒単位の差がPlayerTTLを超えると、アクターはアクターのリストから削除され、再入室は失敗します。
そのため、インアクティブなアクターは、インアクティブ化時間の後、PlayerTTLミリ秒だけルームに再入室できます。
「クイック再入室」は2つのステップで構成されます。
- Reconnect: 切断されたら、適切な接続メソッドを呼び出すだけです。
- Rejoin:
loadBalancingClient.OpRejoin(roomName)
を呼び出します。
セルフホスティング
Photon ServerはLinux上で実行できますか?
できません。
Photon ServerはWindows上でのみ実行可能です。
詳細は「ホスティングと要件」で確認してください。
Photon ServerをAmazon上でホスティングする方法は?
Amazon上でPhoton Serverをホスティングする手順は以下のとおりです:
- 新しいWindows Server EC2インスタンスをセットアップ
- Amazon Web Servicesのアカウントを作成します。
- AWSポータルにサインインします。
- 「Service -> EC2」へ進みます。
- 「Create Instance」セクションで、「Launch Instance」をクリックします。
- 該当の「Select」ボタンを押し、Photon ServerがサポートするMicrosoft Windows Serverのエディションを選択します。
- 「Choose an Instance Type」を選択し、「6. Configure Security Group」へ進みます。
- 新たな セキュリティグループ「Photon Server」を作成し、こちらのページに表示されたとおりに受信ポートを許可します。
- 「Review and Launch」をクリックし、レビュー と「Launch」をおこないます。
- 新規作成するか、または既存のキーペアを選択します。
- 確認トグルボタンをチェックし、「Launch Instances」を押します。
- 「View Instances」をクリックし、インスタンスの初期化が完了するのを待ちます。
- 新しいインスタンスへのRDP接続
- EC2インスタンスを選択します。
- 「Connect」をクリックします。
- 「Get Password」をクリックします。
- プライベートキーをアップロードするか、その内容をコピーし「Decrypt Password」をクリックします。
- 「Download Remote Desktop File」をクリックし、RDPショートカットを取得します。
- ショートカットをダブルクリックし、リモートマシンに接続します。
- 認証情報を入力し、ログインします。
- Photon Server SDKのセットアップ
- Photonアカウントを作成します。
- Photon Server SDKをダウンロードします。
- パッケージを展開し、リモートマシンにファイルをコピーします。
- Photon Controlを起動します。
- Photonをサービスとしてインストールします。
- Photonサービスを起動します。
Threading
単独のPhoton Serverでいくつのスレッドが実行されていますか?
スレッドの利用は以下のように分けられます:
- ネイティブ - 9個のスレッド
- 管理 - .NETデフォルト設定を使用する.NET ThreadPoolにもとづく。
この設定には非常に厳密にテストをおこなってきましたので、広範な負荷プロファイルに対して問題なく動作します。
管理スレッドの使用は、状況によって異なります(.NET Windows Performanceカウンターに記載されたとおりです):
a) 1個~12個まで:通常のPhoton Cloud Realtime負荷に対応
b) 35個以上:プラグイン間の通信(ロッキング)をともなうプラグインを実行するカスタマークラウドが例で、より高いコンテンションの原因となります(弊社のコードとは対照的です)。
備考:必要に応じて.NET ThreadPool設定は調整できます。
これまでデフォルトの設定で適切な成果が得られていますが、各バージョンに応じて調整が必要な可能性があります。
レース状態やその他のマルチスレッドの問題を回避する方法は?
Photonでは、可能な限りシンプルにすることを心がけました:
- 任意のスレッドからPhotonPeerメソッドを使用できます。
- PhotonPeerからのすべての通知は、1つのファイバーで実行されます(ファイバーについては、以下を参照してください)。
- ルーム内のすべてのタスクは1つのファイバーで実行されます。
- ピアは、マルチスレッドの問題からデータを保護するために、ルームのファイバーにメッセージを送信します。
ファイバーは、FIFO方式で1つずつ順番に実行されるタスクのリストです。
これは、それらが1つのスレッドで実行されることを意味しません。
実際には、多くのスレッドで実行されますが、1つずつ実行されます。
したがって、最初のタスクはスレッドAで実行され、終了すると、2番目のタスクはスレッドBで実行されます。
ただし、特定の瞬間に1つのスレッドだけがルームデータにアクセスします。
多くのファイバーが同じデータにアクセスする場合、ロックを使用します。
たとえば、ルームのキャッシュ内の場合です。
次のようにファイバーを使用できます:
C#
// rooms contructor
someFiber = new PoolFiber(); // create new fiber
someFiber.Start();
someFiber.ScheduleForInterval(someRepetitiveRoutine, 0, 100); // start immediately and repeat every 100 ms, ie 10 times per second. this params may vary as you need
// at some other point, where you need to add more logic to the fiber
someFiber.Enqueue(newTask);
someFiber.Enqueue(()=>{ anotherTask(parameters);});
// from the tasks you can send messages to the room e.g. to notify the room of a result of a task
room.EnqueueMessage(new YourCustomMessage(somethingToSend));
同じコードまたは同じデータを共有する複数のカスタムファイバーを使用する場合、異なるファイバーのアクションが同時に実行されるため、アクセスを同期する必要があることに注意してください。
ログの記録
クライアントが接続または切断する度にログエントリーを書く方法は?
アプリケーションのlog4net.configに以下を追加してください:
XML
<logger name="Photon.SocketServer.ApplicationBase">
<level value="DEBUG"/>
</logger>
「{MyApplication}.log」からの出力:
正常な接続:
2013-05-02 11:19:02,506 [23] DEBUG Photon.SocketServer.ApplicationBase [(null)] - OnInit - ConnID=17, IP 127.0.0.1 on port 4530
2013-05-02 11:19:02,506 [23] DEBUG Photon.SocketServer.ApplicationBase [(null)] - OnInit - response sent to ConnId 17 with SendResult Ok
切断:
2013-05-02 11:19:07,608 [24] DEBUG Photon.SocketServer.ApplicationBase [(null)] - OnDisconnect - ConnID=17
Photonがクライアントに作業レスポンスを送信する際にログエントリーを書く方法は?
アプリケーションの「log4net.config」に以下を追加してください:
XML
<logger name="Photon.SocketServer.PeerBase">
<level value="DEBUG"/>
</logger>
「{MyApplication}.log」からの出力:
2013-05-02 11:19:02,569 [21] DEBUG Photon.SocketServer.PeerBase [(null)] - SentOpResponse: ConnID=17, opCode=255, return=0, ChannelId=0 result=Ok size=14 bytes
Photonがクライアントから作業リクエストを受信した際にログエントリーを書く方法は?
この様なログは、アプリケーションのPeerクラス(HivePeer
から継承します)でおこなうのが最適です。
XML
<logger name="Photon.Hive.HivePeer">
<level value="DEBUG"/>
</logger>
「{MyApplication}.log」からの出力:
2013-05-02 11:19:02,553 [21] DEBUG Photon.Hive.HivePeer [(null)] - OnOperationRequest. Code=255
OnOperationRequest
メソッドで、ログエントリーの内容を修正可能です。
C#
protected override void OnOperationRequest(OperationRequest operationRequest, SendParameters sendParameters)
{
if (log.IsDebugEnabled)
{
log.DebugFormat("OnOperationRequest. Code={0}", operationRequest.OperationCode);
}
// snip
}
クライアントが切断する理由は?タイムアウトのデバッグ方法は?
クライアントが切断する理由を確認するには、ピアでOnDisconnect
が呼び出された場合のデバッグログエントリーを書くようにしてください。
XML
<logger name="Photon.Hive.HivePeer">
<level value="DEBUG"/>
</logger>
ピアクラス(HivePeer
から継承します)では、OnDisconnect()
メソッドは以下のようになります:
C#
protected override void OnDisconnect(DisconnectReason reasonCode, string reasonDetail)
{
if (log.IsDebugEnabled)
{
log.DebugFormat("OnDisconnect: conId={0}, reason={1}, reasonDetail={2}", this.ConnectionId, reasonCode, reasonDetail);
}
//
}
「{MyApplication}.log」からの出力:
2013-05-02 11:19:07,639 [12] DEBUG Photon.Hive.HivePeer [(null)] - OnDisconnect: conId=17, reason=ClientDisconnect, reasonDetail=
UDPを使用している場合:「TimeoutDisconnect」の際は、以下のように「reasonDetail」にRoundTripTime履歴が含まれます。
index - sequence - rtt - variance - sentTime - recvTime - cmd_rtt
0 - 326 - 0 - 0 - 830717056 - 830728351 - 11295
1 - 325 - 89 - 19 - 830715918 - 830716042 - 124
2 - 324 - 85 - 14 - 830714826 - 830714904 - 78
3 - 323 - 86 - 17 - 830712751 - 830712813 - 62
4 - 322 - 89 - 14 - 830711659 - 830711737 - 78
5 - 321 - 90 - 16 - 830710551 - 830710645 - 94
6 - 320 - 90 - 19 - 830709428 - 830709537 - 109
7 - 319 - 88 - 19 - 830708320 - 830708414 - 94
8 - 318 - 88 - 23 - 830707197 - 830707306 - 109
9 - 317 - 86 - 24 - 830706105 - 830706183 - 78
10 - 316 - 87 - 29 - 830704701 - 830704763 - 62
... etc ...
各行は以下の値から成ります:
- Index -(0から49の範囲の値をとり、0は最新で49は最も古いです。直近の50個のエントリーのみが表示されます。)
- Sequence - 増加するシーケンス番号
- rtt (RoundTripTime - 最新のRTT、ミリ秒単位 - ACKの処理後、またはタイムアウトの発生後から利用可能です)
- variance (最新の偏差、ミリ秒単位)
- sentTime (コマンドが送信された時刻)
- recvTime (ACKが受信された時刻)
- cmd_rtt ( コマンドが送信されてからACKを受信するまでのタイムスパン、ミリ秒単位)
上記の例では、クライアントのcmd_rttは62ミリ秒から124ミリ秒でした。最後のコマンドに対してACKを受信しなかった後、11秒間にわたって切断しました。
請求
学生、趣味でおこなっているディベロッパー、インディー向けの割引はありますか?
弊社の製品にはすべて、無料プランとワンショットのプランがあります。
また弊社は通常、Unityアセットストアのセールに参加し、また当選者にはクーポンを提供しています。
1つのPhotonアプリケーションに、複数の100CCUプランを組み合わせることはできますか?
いいえ。
100CCUプランは1つのAppIDにつき1回のみ適用でき、複数の100CCUプランを使用することはできません。
複数のPUN+アセットシートを購入している場合には、各AppIDに対して個別の無料100CCUを適用する必要があります。
1つのアプリに対してさらに多くのCCUが必要な場合、次の上位プランは500CCUです。
月額または年額プランをご利用の場合には、その月額/年額プランのCCUに加えて、12ヶ月間有効の100CCUを使用できます。