Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Photon Server Deep Dive - PhotonWireの実装から見つめるPhotonServerの基礎と応用

42,975 views

Published on

2016.09.14 photonstudy

Published in: Technology
  • Be the first to comment

Photon Server Deep Dive - PhotonWireの実装から見つめるPhotonServerの基礎と応用

  1. 1. Work C# Unity Private http://neue.cc/ @neuecc https://github.com/neuecc/UniRx
  2. 2. About Grani モバイル向けゲーム開発企業 http://grani.jp/ 2012年設立 代表作として「神獄のヴァルハラゲート」 GREE Platform Awardにて殿堂入り最優秀賞 他、カプコンとの共同開発による「モンスターハンター ロア オブ カード」 iOS/Android向けに次期タイトル「黒騎士と白の魔王」鋭意開発中
  3. 3. using
  4. 4. using
  5. 5. Unity + Realtime
  6. 6. すべてが別格のRPG https://kuro-kishi.jp Unity ASP.NET Photon
  7. 7. ゲームのメイン部分 チャット・通知系システム
  8. 8. Socket.io ASP.NET SignalR Unity Multiplayer(UNET) モノビットエンジン
  9. 9. サーバー側の分散手法が弱い Unity向けの標準クライアントがない プロトコルが重い 固定のシリアライゼーションフォーマット
  10. 10. C#であること サーバー側にロジックが書けること 大規模MMORPGなどへの発展性があること 実績がある
  11. 11. Photon Family
  12. 12. Realtime/(Turnbased)/Chat/Voice/Server...
  13. 13. サーバーに実装を入れたい
  14. 14. PUN(Photon Unity Network) PUNを使わない100の理由
  15. 15. Getting Started Photon Server
  16. 16. 実態はただのクラスライブラリ 実行フロー
  17. 17. public class Startup : ApplicationBase { // サーバーに接続が入った時のコネクション生成ハンドリング protected override PeerBase CreatePeer(InitRequest initRequest) { if (/* クライアントからのリクエストなら */) { return new MyClientPeer(initRequest); } else // サーバーからのリクエストなら { return new InboundS2SPeer(initRequest); } } protected override void Setup() { // 起動時の処理 // マスターサーバーに繋げるならOutboundS2SPeerを作ったり var outboundPeer = new OutboundS2SPeer(); outboundPeer.ConnectTcp(); } protected override void TearDown() { // 終了時の処理 } } public class MyClientPeer : ClientPeer { public MyClientPeer(InitRequest initRequest) : base(initRequest) { } protected override void OnOperationRequest(OperationRequest operationRequest, { // byte: operationRequest.OperationCode // Dictionary<byte, object>: operationRequest.Parameters // クライアントにレスポンスを送信 this.SendOperationResponse(new OperationResponse(), sendParameters); } protected override void OnDisconnect(DisconnectReason reasonCode, string reaso { } }
  18. 18. // 1. Unity側からサーバーへ送信 var peer = new ClientSidePeer(new MyListener()); peer.OpCustom(opCode: 10, parameter: new Dictionary<byte, object>()); // 2. サーバー側が受信する protected override void OnOperationRequest(OperationRequest operationRequest) { // opCodeで分岐 switch (operationRequest.OperationCode) { case 10: // データはDictionaryに詰まってるのでそれを取り出す(<byte, object>) var parameter = operationRequest.Parameters; /* それを使って何か処理する */ // 3. 処理終わったということでクライアントに結果を送る this.SendOperationResponse(new OperationResponse(operationCode: 5)); break; default: break; } }
  19. 19. // Unityクライアント側 public class MyListener : IPhotonPeerListener { // 4. クライアント受信 public void OnOperationResponse(OperationResponse operationResponse) { // 返ってきたレスポンス switch (operationResponse.OperationCode) { case 5: // なんかする break; } } } // 3. サーバー側:処理終わったということでクライアントに結果を送る this.SendOperationResponse(new OperationResponse(operationCode: 5), sendParameters);
  20. 20. // opCodeで分岐 switch (operationRequest.OperationCode) { case 0: break; case 1: break; case 2: break; case 3: break; case 4: break; case 5: break; case 6: break; case 7: break; case 8: break; case 9: break case 10:
  21. 21. // opCodeで分岐 switch (operationRequest.OperationCode) { case 0: break; case 1: break; case 2: break; case 3: break; case 4: break; case 5:
  22. 22. // opCodeで分岐 switch (operationRequest.OperationCo { case 0: break; case 1: break; case 2: break; case 3: break;
  23. 23. Intro to PhotonWire
  24. 24. byte, Dictionaryを送りswitch、送り返してswitch クライアントの送信と受信がバラバラ
  25. 25. Typed Asynchronous RPC Layer https://github.com/neuecc/PhotonWire
  26. 26. Demo...
  27. 27. 専用のWindowsクライアント
  28. 28. Server to Server
  29. 29. なにもないことはいいこと
  30. 30. Into the Photon Server
  31. 31. 非常にプリミティブ 複雑な機能は全てロジックに寄る
  32. 32. 接続
  33. 33. 4種類ある送信メソッド 当然受信側も4種類
  34. 34. SendEvent/OnEvent SendMessage/OnMessage SendOperationRequest/OnOperationRequest SendOperationResponse/OnOperationResponse
  35. 35. SendEvent/OnEvent SendMessage/OnMessage SendOperationRequest/OnOperationRequest SendOperationResponse/OnOperationResponse
  36. 36. シリアル化 サポート型は少なめ
  37. 37. Next PhotonWire
  38. 38. デシリアライズ速度 シリアライザの置き換え
  39. 39. (De)serialize is slow... ScriptableObject > JsonUtility > (越えられない壁) > MsgPack > XxxJSON
  40. 40. デシリアライズしない新フォーマット C#, Unityにフィットさせる 近日公開予定
  41. 41. Configuration of Photon
  42. 42. <?xml version="1.0" encoding="shift-jis"?> <Configuration> <DevLocal> <!-- CLRVersionを使ってる.NETのバージョンに合わせる。.NET 4.5~6はCLR v4.0 --> <Runtime Assembly="PhotonHostRuntime, Culture=neutral" Type="PhotonHostRuntime.PhotonDomainManager" CLRVersion="v4.0" UnhandledExceptionPolicy="Ignore"> </Runtime> <!-- InactivityTimeout(ms)はローカルでは0にする(デバッガで止めてる最中にも強制切断が辛いので) --> <TCPListeners> <TCPListener IPAddress="127.0.0.1" Port="4530" ListenBacklog="1000" InactivityTimeout="0" /> </TCPListeners> <Applications Default="MyApp.GameServer" PassUnknownAppsToDefaultApp="true"> <Application Name="MyApp.GameServer" BaseDirectory="MyApp" Assembly="MyApp" Type="MyApp.GameServerStartup" EnableShadowCopy="true" EnableAutoRestart="true" ForceAutoRestart="true" ApplicationRootDirectory="PhotonLibs"> </Application> </Applications> </DevLocal> </Configuration>
  43. 43. <?xml version="1.0" encoding="shift-jis"?> <Configuration> <DevLocal> <!-- CLRVersionを使ってる.NETのバージョンに合わせる。.NET 4.5~6はCLR v4.0 --> <Runtime Assembly="PhotonHostRuntime, Culture=neutral" Type="PhotonHostRuntime.PhotonDomainManager" CLRVersion="v4.0" UnhandledExceptionPolicy="Ignore"> </Runtime> <!-- InactivityTimeout(ms)はローカルでは0にする(デバッガで止めてる最中にも強制切断が辛いので) --> <TCPListeners> <TCPListener IPAddress="127.0.0.1" Port="4530" ListenBacklog="1000" InactivityTimeout="0" /> </TCPListeners> <Applications Default="MyApp.GameServer" PassUnknownAppsToDefaultApp="true"> <Application Name="MyApp.GameServer" BaseDirectory="MyApp" Assembly="MyApp" Type="MyApp.GameServerStartup" EnableShadowCopy="true" EnableAutoRestart="true" ForceAutoRestart="true" ApplicationRootDirectory="PhotonLibs"> </Application> </Applications> </DevLocal> </Configuration>
  44. 44. <?xml version="1.0" encoding="shift-jis"?> <Configuration> <DevLocal> <!-- CLRVersionを使ってる.NETのバージョンに合わせる。.NET 4.5~6はCLR v4.0 --> <Runtime Assembly="PhotonHostRuntime, Culture=neutral" Type="PhotonHostRuntime.PhotonDomainManager" CLRVersion="v4.0" UnhandledExceptionPolicy="Ignore"> </Runtime> <!-- InactivityTimeout(ms)はローカルでは0にする(デバッガで止めてる最中にも強制切断が辛いので) --> <TCPListeners> <TCPListener IPAddress="127.0.0.1" Port="4530" ListenBacklog="1000" InactivityTimeout="0" /> </TCPListeners> <Applications Default="MyApp.GameServer" PassUnknownAppsToDefaultApp="true"> <Application Name="MyApp.GameServer" BaseDirectory="MyApp" Assembly="MyApp" Type="MyApp.GameServerStartup" EnableShadowCopy="true" EnableAutoRestart="true" ForceAutoRestart="true" ApplicationRootDirectory="PhotonLibs"> </Application> </Applications> </DevLocal> </Configuration>
  45. 45. <?xml version="1.0" encoding="shift-jis"?> <Configuration> <DevLocal> <!-- CLRVersionを使ってる.NETのバージョンに合わせる。.NET 4.5~6はCLR v4.0 --> <Runtime Assembly="PhotonHostRuntime, Culture=neutral" Type="PhotonHostRuntime.PhotonDomainManager" CLRVersion="v4.0" UnhandledExceptionPolicy="Ignore"> </Runtime> <!-- InactivityTimeout(ms)はローカルでは0にする(デバッガで止めてる最中にも強制切断が辛いので) --> <TCPListeners> <TCPListener IPAddress="127.0.0.1" Port="4530" ListenBacklog="1000" InactivityTimeout="0" /> </TCPListeners> <Applications Default="MyApp.GameServer" PassUnknownAppsToDefaultApp="true"> <Application Name="MyApp.GameServer" BaseDirectory="MyApp" Assembly="MyApp" Type="MyApp.GameServerStartup" EnableShadowCopy="true" EnableAutoRestart="true" ForceAutoRestart="true" ApplicationRootDirectory="PhotonLibs"> </Application> </Applications> </DevLocal> </Configuration>
  46. 46. <?xml version="1.0" encoding="shift-jis"?> <Configuration> <DevLocal> <!-- CLRVersionを使ってる.NETのバージョンに合わせる。.NET 4.5~6はCLR v4.0 --> <Runtime Assembly="PhotonHostRuntime, Culture=neutral" Type="PhotonHostRuntime.PhotonDomainManager" CLRVersion="v4.0" UnhandledExceptionPolicy="Ignore"> </Runtime> <!-- InactivityTimeout(ms)はローカルでは0にする(デバッガで止めてる最中にも強制切断が辛いので) --> <TCPListeners> <TCPListener IPAddress="127.0.0.1" Port="4530" ListenBacklog="1000" InactivityTimeout="0" /> </TCPListeners> <Applications Default="MyApp.GameServer" PassUnknownAppsToDefaultApp="true"> <Application Name="MyApp.GameServer" BaseDirectory="MyApp" Assembly="MyApp" Type="MyApp.GameServerStartup" EnableShadowCopy="true" EnableAutoRestart="true" ForceAutoRestart="true" ApplicationRootDirectory="PhotonLibs"> </Application> </Applications> </DevLocal> </Configuration>
  47. 47. Conclusion
  48. 48. 真価は出してみないとわからん Photon Serverは良い PhotonWireは良い
  49. 49. Hiring http://recruit.grani.jp/

×