7
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Photonを利用した2つの別プロジェクト同士で通信が出来ない事象に遭遇した

Last updated at Posted at 2019-04-19

概要

PhotonRealtime を利用した2つの別のプロジェクト同士で通信させるという少し変わったことをしていたのですが、RPC通信が出来ないという事象に遭遇しました。マッチングが出来てないのではないかと思い、appIdgameVersionroomName を確認しましたが、全て一致していることを確認しました。

ここでは2つのプロジェクトを プロジェクトA , プロジェクトB と呼ぶことにします。
(諸々の事情で PUN1 を利用しています)

事象

プロジェクトA同士, プロジェクトB同士の通信 → 出来る
プロジェクトAとプロジェクトBの通信 → 出来ない

gameVersionroomName の設定は両プロジェクトで下記の通りです。
(appId が同一であることは確認済みです)

PhotonNetwork.ConnectUsingSettings("gameVersion");
PhotonNetwork.JoinOrCreateRoom("roomName", ...);

調査

まずは問題を切り分ける為、基本的なところから調査を行います。

同一のサーバに接続されているか確認する

PhotonNetwork.countOfPlayers を利用して、両プロジェクトが同一のサーバに接続されているかを確認しました。

// プロジェクトAとプロジェクトB
Debug.Log(PhotonNetwork.countOfPlayers) // 1

// プロジェクトAとプロジェクトA
Debug.Log(PhotonNetwork.countOfPlayers) // 2

// プロジェクトBとプロジェクトB
Debug.Log(PhotonNetwork.countOfPlayers) // 2

結果、そもそも両プロジェクトで別のサーバに接続されている事が分かりました。

通信内容を確認する

Wireshark を使い、実際に送信されている appId 等を確認することにしました。
Filter に下記を入力することで、Photon の通信のみを確認出来ます。

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

ただこれだけでは辛いので、Photon の通信プロトコルを解析することにします。
バイナリプロトコル | Photon Engine に Photon の通信プロトコルの仕様があります。
また、AltspaceVR/wireshark-photon-dissecto のLuaでプロトコルの解析が可能です。
(ProtoField.bytes の引数にバグあり、base.HEX の記述を削除する。)

Lua 拡張読み込みは Wireshark(Ethereal)で独自パケットフォーマットを解析する方法 参照してください。
Lua の Photon 拡張を読み込んで Wireshark で確認すると下記のようになります。

2feac96c7a1d7fe1ed6ab5d1e0154b41.png

これで通信内容が見えるようになったのは良いのですが、肝心の appId が見つけられなかったので断念しました。

PUNのログを確認する

SupportLogger と呼ばれる PUN に含まれるロギング用コンポーネントを利用します。
これは任意の GameObject にアタッチするとログを吐いてくれます。
詳細は Analyzing Disconnects | Photon Engine を参照して下さい。

これを利用してログを確認すると、各プロジェクトで gameVersion が異なっていることが確認出来ました。

プロジェクトB
SupportLogger Info: PUN 1.91: AppID: 1*** GameVersion: gameVersion_1.91 ...


プロジェクトB
SupportLogger Info: PUN 1.94: AppID: 1*** GameVersion: gameVersion_1.94 ...

原因

gameVersion は末尾に PUN のバージョンが付与されて、正しくマッチング出来ていないことが原因でした。
(Photon公式にも違うバージョンの PUN 同士では通信出来ないとか書いてあったような気がする?)

  • プロジェクトA: gameVersion_1.91
  • プロジェクトB: gameVersion_1.94

対策

該当コードは NetworkingPeer.cs の下記コードです。

internal class NetworkingPeer : LoadBalancingPeer, IPhotonPeerListener
{
    /// <summary>Combination of GameVersion+"_"+PunVersion. Separates players per app by version.</summary>
    protected internal string AppVersion
    {
        get { return string.Format("{0}_{1}", PhotonNetwork.gameVersion, PhotonNetwork.versionPUN); }
    }

Restricting joining room with non-matching game version — Photon Engine に対策がありましたが、この対策は PUN1 では利用出来なかった為、暫定的に今回は上記コードを下記のように変更して対策しました。

internal class NetworkingPeer : LoadBalancingPeer, IPhotonPeerListener
{
    /// <summary>Combination of GameVersion+"_"+PunVersion. Separates players per app by version.</summary>
    protected internal string AppVersion
    {
        // TODO: これをコメントアウトして、gameVersion だけ返すようにする
        // get { return string.Format("{0}_{1}", PhotonNetwork.gameVersion, PhotonNetwork.versionPUN); }
        get { return PhotonNetwork.gameVersion; }
    }

RPC通信のエラー

RPCのindexが合ってない

これでマッチングは出来るようになりましたが、下記エラーによりRPC通信は失敗しました。

Could not find RPC with index: 18. Going to ignore! Check PhotonServerSettings.RpcList

これはRPCのindexが両プロジェクトで一致していないことが原因のようです。
下記リンクで質問が上がっていましたが、解決には至っていないようでした。
Could not find RPC with index: 17. Going to ignore! Check PhotonServerSettings.RpcList — Photon Engine

ただ、両プロジェクトでRPCのindexを完全に一致させたところ、無事にこのエラーは消えました。
(下記画像は上記リンクより拝借、これを両方で合わせる)

image

RPCが書いてあるスクリプトのPhotonViewIDが一致していない

index関連のエラーは消えましたが、今度は下記エラーが出ました。

PhotonView with ID 1 has no method "xxx" marked with the [RPC](C#) ... 

RPCを持つスクリプトをアタッチしたゲームオブジェクトには PhotonView をアタッチする必要があります。
アタッチした PhotonView には ViewID を割り当てますが、これが両プロジェクトで一致している必要がありました。

そこで RPC の index と PhotonViewID を一致させたところ、下記のように別プロジェクト同士で位置同期が確認出来ました!(ちょっと分かりづらくてすみません)

image

まとめ

Photonエンジンは別プロジェクト同士で利用されることが想定されていないことが分かりました。
これは RPC が index や PhotonViewID に依存していることから明らかです。

Photon はプロジェクト立ち上げ時は便利なのですが、内部がブラックボックスなのがネックでした。
オンラインの同期は独自実装か、日本語サポートが充実しているモノビットを使うのが良さそうですね。

7
5
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?