PUN Classic (also called PUN1) is the original and first major version of PUN. It is now replaced by PUN2 which is refactored and enhanced. We highly recommend starting new projects with PUN2 and if possible migrating existing ones from PUN1 to PUN2 by following our "Migration Notes". PUN Classic will be maintained for the coming months. We will fix important bugs and support new Unity versions but new features will be added only to PUN2.

接続が切断された場合の調査

オンラインマルチプレイヤーゲームを構築する際には、クライアントとサーバー間の接続が失敗する場合を想定しておく必要があります。

切断の原因は、ソフトウェアまたはハードウェアです。 接続のいずれかのリンクが失敗すると、メッセージの遅延や、欠落、破損が発生し、接続をシャットダウンしなければなりません。

切断が頻繁に起きる場合は、いくつか解決策を試してみてください。

Contents

切断の理由

クライアントが全く接続不可能というケースもあります。(サーバー未到達、サーバーアドレスの誤り、DNSが使用不可、セルフホストサーバーの未起動など)このような場合では、接続の切断ではなく「(初期)接続不良」と考えられます。

クライアントSDKは切断コールバックの用意があり、切断の要因となります。 予期せぬ切断が発生した場合はこれらの調査を行ってください。 主な切断の要因を並べてみました。これらはクライアント側かサーバー側どちらでも発生します。

Back To Top

クライアントによる切断

Back To Top

サーバーによる切断

  • サーバー側のタイムアウト: クライアントからのACKがない、または遅すぎることが原因。詳細はタイムアウトによる切断を参照してください。
  • サーバーのバッファフル送信(メッセージ過多)。「[トラフィックの問題とバッファフル](#trafficissuesandbufferfull」 を参照してください。
  • ライセンス、または購入CCUの上限に到達。

Back To Top

タイムアウトによる切断

通常のUDPと異なり、PhotonのリライアブルなUDPプロトコルはサーバーとクライアント間の接続を確立します: UDPパッケージ内のコマンドはリライアブルである場合、連番とフラグがあります。 その場合、受信側はコマンドに肯定応答する必要があります。 リライアブルなコマンドは、肯定応答が届くまで短いインターバルで繰り返されます。 肯定応答が届かなければ、接続はタイムアウトします。

両者がそれぞれの立場から接続を監視します。もう片方が使用可能かを決定するのにそれぞれにルールがあります。

タイムアウトが検出されると、接続のタイムアウトが検出された側で切断が発生します。 一方が、片方がもう応答しないと判断した場合、何のメッセージも送信されません。 タイムアウト切断が片方でのみ発生して同期的でないのはそのためです。

タイムアウトによる切断は「まったく」接続できない問題を除けば、もっとも多く発生する問題です。

頻繁にタイムアウトが発生する場合、障害の発生箇所は1つではありません。問題の原因として考えられるシナリオや、修正方法は複数あります。

簡単なチェックリストを以下に用意しました。

  • 送信するデータ量を確認します。 データ量が急増したり、メッセージもしくはメッセージ/秒レートが非常に高くなっている場合、接続の質に関わります。 「送信量を減らす」を参照してください。

  • Check if you can reproduce the issue on other hardware and on another network. See "Try Another Connection". 他のハードウェアやネットワーク上でも同じ問題が再度発生するかどうか確認します。 「別の接続を試す」を参照してください。

  • 再送信する数とタイミングを調整します。「再送信の調整」を参照してください。

  • モバイルアプリケーションを作成している場合、モバイル・バックグラウンドアプリケーションを参照してください。

  • ブレイクポイントを使用してゲームのデバッグを行う場合、こちらを参照してください。

Back To Top

トラフィックの問題とバッファフル

通常Photonサーバーおよびクライアントはパッケージに実際に置かれてインターネット経由で送信される前に複数のコマンドをバッファします。 バッファフルの問題は、「メモリ不足」の問題に似ています。 Photon Serverとクライアントは、実際にパッケージされインターネット経由で送信される前に、通常はいくつかのコマンドをバッファします。 これにより複数コマンドを(より少ない)パッケージに集約できるようになります。

いずれかの側が大量のコマンドを発生した場合(たとえば、大きなイベントを大量に送信するなど)、バッファ不足になる可能性があります

バッファを充填すると、さらにラグが生じる原因になります: イベントが反対側に受信されるまでに、通常より長く時間がかかることがわかります。 また、オペレーションのレスポンスが通常よりも遅くなります。

送信料を減らす」を参照してください。

Back To Top

緊急処置

ログを確認する

これは、最初に確認すべき事項です。

すべてのクライアントには、内部ステートの変化や問題についてのログメッセージを提供する、なんらかのコールバックがあります。 これらのメッセージのログを作成し、問題が発生した場合にはログにアクセスしてください。

有用な情報が表示されない場合には、ロギングを増加することができます。 ロギングを増加させる方法は、APIリファレンスを確認してください。

サーバーをカスタマイズしている場合には、そのサーバーのログを確認してください。

Back To Top

SupportLoggerを有効化する

SupportLoggerは 頻繁に必要とされる情報をログしてPhotonの問題をデバッグするツールです。(短縮した)AppId、バージョン、リージョン、サーバーIP、一部のコールバックなどがその例です。

PUN Classicでは、SupportLoggerはコンポーネントとなります。 シーンに、接続前に有効化される空のGameObjectを作成します。 SupportLoggerコンポーネントを追加して準備完了です。 コンソールとログには新しいログエントリが含まれます。

Back To Top

別のプロジェクトを使用

PhotonのすべてのクライアントSDKには、複数のデモが含まれています。 これらの中から、対象となるプラットフォームのデモを使用してください。 デモが失敗する場合には、接続に問題が生じている可能性があります。

Back To Top

別のサーバーまたはリージョンを使用

Photon Cloudを使用している場合には、別のリージョンを簡単に使用できます。

独自にホスティングをおこなう際は、仮想マシンではなく物理マシンを使用しましょう。 サーバーに近いクライアント(ただし同一マシン上やネットワーク上ではなく)で最小ラグ(ラウンドトリップタイム)をテストしましょう。 顧客の近くにサーバーを追加する事も検討してみてください。

Back To Top

別の接続を使用

特定のハードウェアが原因で接続に失敗する場合があります。 他のWifiやルーターなどを試してみてください。 別のデバイスで作動状況が改善するか確認してください。

Back To Top

代替のポート番号を使用

2018年初めからPhoton Cloudのすべての実装で、新しいポート番号の範囲をサポートしています: 新しいポート番号の範囲は5055から5058を使用せず、27000から開始します。

ポートを変更しても違いがないように思えるかもしれませんが、実際には非常に効果的です。 現時点では、とても高い評価のフィードバックをいただいています。

PUNでは、接続する前に PhotonNetwork.UseAlternativeUdpPorts = trueを設定します。

Back To Top

CRCチェックを有効化

クライアントとサーバー間でパッケージが破損する場合があります。 ルーターまたはネットワークが非常にビジーな状態の場合に、 こうした破損が生じる可能性が高まります。 またハードウェアやソフトウェアによってはバグが多く、破損が発生する可能性が十分にあります。

hotonにはオプションでパッケージごとのCRC Checkがあります。 パフォーマンス上の問題が生じるため、デフォルトでは有効化されていません。

ただし有効化した場合にはサーバーもCRCを送信します。

接続の前にPhotonNetwork.CrcCheckEnabled = trueを設定します。

Photonクライアントは、CRC Checkの有効化によって何個のパッケージが欠落したかをトラッキングします。

PhotonNetwork.PacketLossByCrcCheckをモニタリングすることも可能です。

Back To Top

微調整

トラフィックの統計を確認する

一部のクライアントプラットフォームでは、Photonで直接Traffic Statisticsを有効化できます。 トラフィックの統計では、様々なパフォーマンスインジケーターがトラッキングされ、ログを容易に作成できます。

トラフィックの統計は、C#ではLoadBalancingPeerクラス内のTrafficStatsGameLevelプロパティとして利用可能です。 このプロパティによって興味深い値を参照できます。

たとえば、TrafficStatsGameLevel.LongestDeltaBetweenDispatchingを使用して連続するDispatchIncomginCommandsコール間の最長の間隔を確認してください。 もしこの間隔が数ミリ秒以上ならば、ローカルラグが発生している可能性があります。 LongestDeltaBetweenSendingを参照して、クライアントが頻繁に送信しているか確認してください。

TrafficStatsIncomingプロパティとTrafficStatsOutgoingプロパティは、送受信されるbyteやコマンド、パッケージについてより詳細な統計を提供します。

Back To Top

再送信を微調整

PUNには、再送信のタイミングを微調整するための2つのプロパティがあります:

Back To Top

QuickResends

PhotonNetwork.QuickResendsは受信側が確認できない高信頼性コマンドを速く繰り返します。 結果として、いくつかのメッセージが欠落した場合にトラフィックが少し増加し、遅延が短くなります。

Back To Top

MaxResendsBeforeDisconnect

PhotonNetwork.MaxResendsBeforeDisconnectはクライアントが個々の高信頼性メッセージをどのくらいの頻度で繰り返すかを定義します。 繰り返しの速度が速いならば、繰り返しの頻度も上げる必要があります。

PhotonNetwork.QuickResendsを3に、PhotonNetwork.MaxResendsBeforeDisconnectを7に設定することで状況が改善する場合があります。

繰り返しを増やすことで接続状況が慶全されるとはkぎりません。また、遅延がより長くなる可能性があります。

Back To Top

再送信された高信頼性コマンドを確認する

ResentReliableCommands. ResentReliableCommandsの監視を開始する必要があります。

このカウンターは高信頼性コマンドが送信されるたびに増加します(サーバーからの確認が時間内に受信されなかったため)。

PhotonNetwork.ResentReliableCommands

もしこの値が上限を超えると接続は不安定になり、パケットは正常に送信されません(どちらの方向にも)。

Back To Top

送信量を減らす

トラフィックの問題を避けるには、送信量を減らします。 送信量を減らすには、いくつかの方法があります:

Back To Top

必要以上に送信しない

必要な分だけ通信してください。 関連する値のみを送信し、それらの値から出来る限り派生させてください。

状況に応じて、送信するものを最適化してください。 何を送信するべきか、また送信頻度を考慮するようにしましょう。 重要でないデータは同期によって強制的に再計算される場合を除き、同期されたデータ、またはゲームの進行内容にもとづいて受信側で再計算されるべきではありません。

例:

  • RTSでは、発生時に複数のユニット向けに「オーダー」を送信できます。 これは1秒間に10回の頻度で各ユニットに位置、回転、速度を送信するよりもはるかに効率的です。

    1500 archersを参照してください。

  • シューティングゲームでは、発射は位置と方向として送信してください。 銃弾は通常、直線で飛びます。このため、100ミリ秒ごとにそれぞれの位置を送信する必要はありません。 銃弾が何かに当たった場合、または銃弾が「非常に多くの」ユニットを通過した後には、銃弾をクリーンアップすることができます。

    それぞれの銃弾をインスタンス化したり、破壊する必要はありません

  • アニメーションは送信しないでください。通常は、プレイヤーの入力やアクションからすべてのアニメーションを派生することができます。 アニメーションを送信すると遅延が発生する可能性が十分にあり、プレイが遅延すると非常に不自然な印象を与えます。

  • デルタ圧縮を使用してください。前回の送信から変更があった値のみを送信してください。 受信側での値を平滑化するため、データ補間を使用してください。 この方法は無理に同期をおこなうよりも望ましく、トラフィックを軽減します。

Back To Top

送信量を抑える

やり取りする型とデータ構造を最適化してください。

例:

  • 小さな整数の場合には、intではなくbyteを使用してください。可能であれば、floatではなくintを使用してください。
  • stringのやり取りを避け、なるべくenumやbyteを使用してください。
  • 送信されるものが明確でない限り、カスタムの型をやり取りしないでください。

  • ほとんどの場合にキャラクターは垂直軸の周りを回転するため、一般的にキャラクターを回転する際にはVector3のやり取りはしないでください。 垂直回転を抽出するには、追加のコードを作成してください。このコードを送信することで、そのパラメータのサイズを3分の1に軽減できます。

  • データを配列に組み込まないでください。 すべての変数についてstream.SendNext()を使用し、個別に分割してください。
  • カスタムプロパティを使用しすぎないように留意してください。 長時間実行されるゲームで多くのカスタムプロパティを設定すると、参加するプレイヤーは多くの項目についてキャッチアップしなければなりません。 ルームへの参加時に、多くのクライアントの接続が切断される場合には、この点を確認してください。

静的なデータ、またはよりサイズの大きなデータをダウンロードするには、別のサービスを使用してください(例:マップ)。

Photonはコンテンツ配信システムとして構築されていません。 HTTPベースのコンテンツシステムを使用したほうがコストを抑えられ、管理も容易です。 最大転送単位(MTU)よりも大きなものはすべて分割され、複数の信頼性の高いパッケージとして送信されます(完全なメッセージへと再構成する必要があります)。

Back To Top

送信頻度を抑える

  • 送信レートを下げてください。できれば、10未満に下げることを推奨します。 この設定は、当然のことながらゲームプレイに応じて異なります。 この変更はトラフィックに大きく影響します。

ユーザーのアクティビティや、やり取りするデータにもとづいて、適応送信レートや動的送信レートを使用できます。この設定もトラフィックに大きく影響します。

  • 可能な場合には信頼性を低くして送信してください。 新たなアップデートをすぐに送信する必要がある場合、通常は信頼性の低いメッセージを使用できます。 信頼性の低いメッセージは、繰り返しを発生しません。 例:FPSでは、通常プレイヤーの位置は信頼性を低くして送信されます。

      Back To Top

    より低いMTUを試す

クライアント側で設定すれば、通常よりも最大パッケージサイズを小さくしてサーバーやクライアントで使用することができます。 MTUを低くするとメッセージ送信の際により多くのパッケージが必要ですが、他の方法でも改善しない場合にはこの方法を試してみてください。

この方法の結果について弊社では確認できていませんので、状況が改善したかどうかぜひ弊社にお知らせください。

PhotonNetwork.networkingPeer.MaximumTransferUnit = 520;を設定してください。

Back To Top

ツール

Wireshark

このネットワークプロトコルアナライザーおよびロガーは、ゲームのネットワークレイヤーの状況を把握するのに非常に有用です。 このツールを使用すると、ネットワークの観点から詳細な状況が分かります。

Wiresharkは複雑そうに思えますが、実際にはゲームのトラフィックのログは非常に簡単な設定で取得できます。

インストールして起動します。 最初のツールバーアイコンから(ネットワーク)インターフェースのリストを開きます。

PhotonServerSettings in Inspector
Wireshark ツールバー

トラフィックのあるインターフェースの横のボックスにチェックマークをつけます。 不明な場合には、複数のインターフェースのログを取得してください。 次に「Options」をクリックします。

PhotonServerSettings in Inspector
Wireshark - Capture Interfaces

すべてのネットワークトラフィックは必要ではないため、チェックマークをつけたインターフェースごとにフィルタを設定する必要があります。 次のダイアログボックス(「Capture Options」)で、チェックマークをつけたインターフェースをダブルクリックします。 「Interface Settings」ダイアログボックスが開きます。 ここでフィルタを設定できます。

PhotonServerSettings in Inspector
Wireshark - Interface Settings

Photonに関するログを取得するフィルタは以下の通りです:

(udp || tcp) && (port 5055 || port 5056 || port 5057 || port 5058 || port 843 || port 943 || port 4530 || port 4531 || port 4532 || port 4533 || port 9090 || port 9091 || port 9092 || port 9093 || port 19090 || port 19091 || port 19093 || port 27000 || port 27001 || port 27002)

「Start」を押すと、接続後にロギングが開始されます。 問題を再現できたらロギングを停止し(ツールバーの3番目のボタン)保存します。

何をおこなったのか、そしてエラーが定期的に発生する場合には発生頻度や発生日時(ログにはタイムスタンプがあります)も記載してください。 クライアントソースログも添付してください。

.pcapやその他のファイルをメールで送信いただければ、弊社で調査をおこないます。

Back To Top

プラットフォーム固有の情報

Unity

PUNはインターバルでServiceコールを実装しています。

ただしUnityは、シーンやアセットをローディングしている際や、スタンドアロンプレイヤーのウィンドウをドラッグしている際には Updateを呼び出しません。

シーンのローディング中も接続を維持するには、PhotonNetwork.IsMessageQueueRunning = falseを設定する必要があります。

メッセージキューを一時停止することで2つの効果があります:

  • バックグラウンドスレッドはSendOutgoingCommandsを呼び出し、Updateは呼び出されません。 これにより、イベントや操作(RPCまたは同期アップデート)は送信されず肯定レスポンスのみが送信され、接続が維持されます。 受信中のデータはこのスレッドによって実行されません。
  • 受信中のアップデートは全てキューされます。RPCは呼び出されず、アップデートされたオブジェクトの監視もされません。 レベルを変更している間、メッセージキューを一時停止していると前のレベルでのRPC呼び出しを防ぎます。

Photon Unity SDKを使用している場合、おそらくMonoBehaviour UpdateメソッドでServiceコールを行うことになります。

シーンのローディング中、PhotonクライアントのSendOutgoingCommandsが確実に呼ばれるようにするため、バックグラウンドスレッドを実装します。 このスレッドが一時停止するのは、各呼び出し間で100~200ミリ秒なので、パフォーマンスがすべて失われることはありません。

To Document Top