【photon勉強会】ffgmでも採用!1時間でわかるplugin開発とenterprise cloudの詳解

Post on 14-Apr-2017

911 Views

Category:

Technology

0 Downloads

Preview:

Click to see full reader

TRANSCRIPT

1 時間でわかる Plugin 開発と Enterprise Cloud の詳解

Photon 運営事務局シニアテクニカルアドバイザー並木 健太郎

アジェンダ• Photon の外部連携方法• Plugin とは、その詳細• Enterprise Cloud と Plugin

Photonの外部連携方法

Photon のしくみ• すべてのクライアント (=プレイヤー ) はサーバーへ接続する• サーバーはクライアント間の通信を仲介する役割

Photon

Client Client Client

SDK SDK SDK

大前提として…• Photon はストレージ機能などは一切持っていません• アカウント管理などで何かしらのストレージが必要になる場合が一般的• データ保存に関しては、今まで通り Web サービス & ストレージ (DB など ) で作ってください

Web サービスと Photon• Web サービスと Photon は必ずしもつなげる必要はありません• Web サービスでマルチプレイの準備をして、 Photon でマルチプレイを行い、その結果を

Web サービスに戻せば基本的には OK

ClientClient

Web Service準備

ClientClient

PhotonマルチプレイClientClient

Web Service結果

でもそれじゃ不安…• マルチプレイ中の状況を把握したい• ゲームのコントロールをサーバー側から行いたい• チート対策をしたい

プレイ中に Photon との連携が必要になる場合も!

Photon の外部連携方法• Webhooks & WebRPC• Photon Server でカスタマイズ• Plugin でのカスタムコード実装

Webhooks & WebRPC• ルーム内でのイベント発生時(ルーム作成、入室、プロパティ設定など)に予め設定しておいた Web サービスを呼び出すことができる• 発生源、情報は Photon -> Web サービスの片方向( WebRPC の情報は逆も可)• Photon のサーバー側は設定するだけでコーディングの必要性なし

Photon Server でカスタマイズ• Photon のサーバー側アプリに独自コードを入れることにより、あらゆる挙動を変更したり、ゲーム独自の動作をさせることが可能• 自前の運用が必須、アップデートの管理などもお客さま自身で行う必要あり• ルームだけでなくロビーもカスタマイズ可能

Plugin でのカスタムコード実装• Webhooks と同様にルーム内のイベント発生時にコールバックとして呼ばれ、サーバー内でカスタムコードを動かすことが可能• 基本はイベントドリブンになるが、タイマーを使うことにより主体的に動くことも可能• ルーム内でのみ動作

自由度と手軽さ、運用負荷• 自由度

Webhooks << Plugin < Server カスタマイズ• 手軽さ

Server カスタマイズ << Plugin < Webhooks• 運用負荷

Webhooks << Plugin <<< Server カスタマイズ

Pluginとは、その詳細

Plugin とは• .NET(C#) の DLL• Photon Server の LoadBalancing アプリの上で動作し、ルーム内イベントで動く• ひとつのアプリで使える Plugin は 1DLL だが、 1DLL 内に複数の Plugin を実装することは可能

Plugin の内部構造

Hive

PluginPluginFactory : IPluginFactory

var plugin = new HogePlugin();return plugin;

1.

2.

HogePlugin : PluginBase(IGamePlugin){

public OnCreate(...) { ... }}

HogePlugin : PluginBase(IGamePlugin){

public OnCreate(...) { ... }}

HogePlugin : PluginBase(IGamePlugin){

public OnCreate(...) { ... }}

3.

PluginFactory• Plugin のインスタンスを生成するためのクラス• Hive より Room 生成時に呼ばれる– 実際に呼ばれるのは Create() メソッド– ここで指定された Plugin 名や config を受け取る

• 指定された情報を元に Plugin のインスタンスを生成し、戻り値として返すのが仕事

最小実装例namespace HogePlugin { public class PluginFactory : Photon.Hive.Plugin.IPluginFactory { public IGamePlugin Create(...) { var plugin = new HogePlugin(); if (plugin.SetupInstance(gameHost, config, out errorMsg)) { return plugin; } return null; } }}

なんで Factory がいるの?• Plugin を 1 つだけ動かすなら不要でした• 複数の Plugin をサポートする 0.9 より実装• Plugin 名を見て生成するインスタンスを分ける必要がある• Plugin 生成を柔軟に対応できる

Client と Plugin• Room 作成時、 RoomOptions.Plugins を設定することにより Plugin のリクエストが可能– RoomOptions.Plugins = new string[] { "SomePlugin" };

• 配列になっていますが、現在は 1 つ目のみサポート• PluginFactory で失敗した場合は、 Client に

PluginMismatch のエラーが返る

Plugin の実クラス• IGamePlugin を実装する• 実際は最低限を実装している

Photon.Hive.Plugin.PluginBaseを継承して実装するのがおすすめ– 必要なメソッドだけ実装することが可能

プロパティ• Name: Plugin 名– ゲーム開始後、 Client がどの Plugin で動いているかを確認する

• Version: Plugin のバージョン– 同上。設定側で決めることも可能

• PluginHost: Plugin のホスト I/F– Hive 側とのやりとりを行うクラス

各コールバックの説明• ICallInfo の説明が必要なので、もう少し待ってください…

ICallInfo• 各コールバックのパラメータは ICallInfo をベースに作られています• 実際は ICallInfo からそれぞれのコールバック毎に再定義されています– 例 : ICreateGameCallInfo : ICallInfo

ICallInfo の重要な仕事• リクエストデータなどにアクセスするため– ICallInfo.Request

• このリクエストを処理するかどうかをHive に伝える– ICallInfo.Continue(), Cancel(), Fail(), Defer()

ICallInfo の Methods• Continue(): 処理継続

– 通常通り処理します• Cancel(): 静かに破棄

– 処理は中断、クライアントへのエラー通知なし• Fail(): エラー

– 処理は中断、エラーがクライアントに返される• Defer(): 処理を遅延

– 処理を一旦遅らせ、後で再度判断を行う

どう使うの?• Fail()– Room 作成時に条件を満たさないユーザーの Room 作成を拒否する( Room参加時も同様に)

• Cancel()– 不正なイベントが送られてきたので、破棄させる

• Defer()– 外部へ HTTP アクセスする場合で、レスポンスの内容を確認してから処理する

コールバック一覧• BeforeCloseGame()• BeforeJoin()• BeforeSetProperties()• OnCloseGame()• OnCreateGame()• OnJoin()

• OnLeave()• OnRaiseEvent()• OnSetProperties()• OnUnknownType()

• SetupInstance()

Room 作成・入室• Room が存在しない場合– OnCreateGame()

• Room が存在する場合– BeforeJoin()

• 入室させる前に情報を収集して OnJoin() で判断が可能– OnJoin()

Room退出・削除• Room から Player が退出した時– OnLeave()

• Room が Server 上のメモリから削除される時(EmptyRoomTTL経過後 )– BeforeCloseGame()– OnCloseGame()

イベント受信・プロパティ設定• イベント受信

– OnRaiseEvent()• httpForward のフラグに関わらず送信される• Cancel() も可能

• プロパティ設定( Room, Player共通)– BeforeSetProperties()

• ここで Cancel() が可能• ここで Continue() すると、プロパティの設定が行なわれる

– OnSetProperties()

Plugin の準備• SetupInstance()– PluginFactory() から呼ばれる– Plugin の初期化を行い、利用できる状況にする

Plugin のインスタンス• Plugin のインスタンスは Room毎に作られる• Room の新規作成か復元時に生成され、 Roomから全員退出し TTL を超えるまで存在• SetupInstance() と OnCreateGame() は同じようなタイミングで呼ばれますが、全く違うものです– SetupInstance() は Plugin の初期化– OnCreateGame() は Room 作成処理

スレッドモデル• Plugin のインスタンス毎• 1Room 内は非同期アクションを含め 1 スレッドなので、 Room 内でスレッドを意識する必要はなし• Room をまたいで共有メモリなどを使う場合は注意を

Plugin の中でできるアクション• イベント送信• タイマー• HTTP アクセス• プロパティ設定• キックアウト

イベント送信• IPluginHost.BroadcastEvent() を使って送信• ターゲット指定により 2 つのオプション– 送信先の ActorNr の List を渡す– targetGroup で送信先を指定する

• senderActor を 0 にすると Server から送られたと Clientは認識• イベントコードやデータの扱いはクライアントからの扱いと同様

使用例public void TimerAction() { ... PluginHost.BroadcastEvent(ReceiverGroup.All, 0, 0, 1, new Dictionary<byte, string> { 1, "test" }, 0);}

class TestPlugin : PluginBase { ... this.BroadcastEvent(2, new Directory<byte, string> { 1, "params" });

タイマー• 1回のみと繰り返しの 2種類を用意• Action を指定して、初回起動までの時間、繰り返しの場合は 2回目以降の時間を指定すれば OK

使用例public override void BeforeSetProperties(IBeforeSetPropertiesCallInfo info) { PluginHost.CreateOneTimeTimer( () => info.Continue(), 2000); info.Defer();}

public void TimerAction() { ... }

object timer = PluginHost.CreateTimer(this.TimerAction, 2000, 1000); ... PluginHost.StopTimer(timer);

HTTP アクセス• 外部への HTTP アクセスは

IPluginHost.HttpRequest を利用してください• HttpRequest クラスでリクエストを構築し、

IPluginHost.HttpRequest で送信• 同期、非同期どちらも可能です

実装例 -非同期public override void OnRaiseEvent(IRaiseEventCallInfo info) { ... HttpRequest request = new HttpRequest() { Callback = OnHttpResponse, Url = "https://hogehoge.com/hogehoge", Async = true, UserState = info }; PluginHost.HttpRequest(request); info.Defer();}

実装例 -非同期 (続き)public override void OnHttpRequest(IHttpReponse response, object userState) { ICallInfo info = userState as ICallInfo; ... if (info.IsDeffered) { info.Continue(); }}

実装例 -JSON string json = "..."; var stream = new MemoryStream(); var data = Encoding.UTF8.GetBytes(json); stream.Write(data, 0, data,length); HttpRequest request = new HttpRequest() { Callback = callback, Url = "https://api.hoge.com/api/json", DataStream = stream, Method = "POST", ContentType = "application/json" }; PluginHost.HttpRequest(request);

プロパティ設定・キックアウト• Plugin 内からのカスタムプロパティの設定が可能です– IPluginHost.SetProperties()

• キックアウト– IPluginHost.RemoveActor()

Plugin のマニュアルについて• その他詳細については、下記をご覧ください• http://doc.photonengine.com/ja-jp/onpremis

e/current/plugins/manual• 現在英語になっておりますが、間も無く日本語化予定です、少々お待ち下さい

Plugin TIPS• Namespace は自由に設定してください– が、 Plugin 内では統一してください

• Plugin 名に Default は使えません• Plugin の名前はクラス名と合わせておくのがわかりやいでしょう

開発を始めるにあたり• 開発は Photon Server の SDKページにある、

Plugin SDKをダウンロードして、 Webhooks のソリューションとプロジェクトをコピーしてください

サンプル• サンプルは、 Server SDK (Plugin SDK でない ) にある、 LoadBalancing ソリューション内の TestPlugins プロジェクトがお勧めです• 十数個の Plugin を 1 つの DLL でまとめているので、複数 Plugin のサンプルとしてもお勧めです

Plugin での実装範囲• Photon 内部で完結する処理は Plugin 内にて実装– 特定のイベントを受信したら、プロパティを設定する– 定期的に情報を更新してイベントを発生させる

• 外部ストレージが絡む場合などは処理そのものは外部で行い、 HTTP でアクセス– 直接 DB にアクセスなどは決してお勧めしません

Plugin での実装範囲

Photon

Plugin Web Server

DB

OnSetProperties値チェック⇨ここで実装

OnJoinRoom参加者チェック &記録⇨ HTTP で呼ぶ

参加者チェック &記録⇨ここで実装

Plugin のメリット• Photon Server のコードと、カスタムコードを完全に分離することが可能• 独立してデプロイができ、互いに干渉せずにアップデートも可能!• Photon Server をご検討でも、ぜひ Pluginでカスタマイズしてみてください!

Enterprise Cloudと Plugin

Plugin のデプロイ• 各サーバーに Plugin DLL を設置すれば OK• Photon Server の再起動は必要です• 設定の変更は XML の設定ファイルを変更する必要あり

Plugin で運用負荷は減りますが…• 多くのサーバーがある場合、 Plugin DLL をアップデートするのは面倒• Plugin 設定を 1台ずつ変更するのも面倒…もっと楽しませんか?

Enterprise Cloud とは• Photon Cloud の上位サービス• Private Cloud として、サーバーを専有• 複数のタイトルでの利用も可能• クラウドサービスなので、サーバー運用不要• 運用体制も万全

Enterprise Cloud でのデプロイ• Plugin の DLL などを ZIP で固めて、 PowerShell のツールでアップロードすれば完了!• 複数バージョンに対応、適用はダッシュボードで Version を切り替えるだけ、ロールバックも簡単• Photon Server の Plugin そのまま使えます

Enterprise Cloud での設定• ダッシュボード上で、設定値を変更すれば反映される

ステージング対応• アプリケーション (AppID)毎に Plugin の設定を変更可能• ステージング用 AppID 、本番用 AppID を分けることにより、ステージング環境で十分テストをして、その後本番に適用させることも可能

Cloud vs. Enterprise CloudCloud• Public サービス (共有 )• 10,000CCU まで• Webhooks 対応• 複数タイトル共有不可• サーバー設定変更不可

Enterprise Cloud• Private サービス (専有 )• CCU 上限なし• Webhooks & Plugin 対応• 複数タイトル共有可能• サーバー設定変更可能

Enterprise Cloud + Plugin• Photon も Plugin も運用フリー!• Client と Plugin の開発に注力できます!• 開発工数、運用工数を削減して、コンテンツ開発に注力してください!

まとめ

今後の予定• 6/4(土 ) Photon ってぶっちゃけどないやねん !!CCS がはじめて Photon を使ってみた話@GMO Yours ( 大阪 )• 6月 ( 予定 ) モンスターストライク運営の XFLAG さまと合同勉強会@GMO Yours (渋谷 )• 7/5(火 ) GTMF 大阪@ グランフロント内

7/15(金 ) GTMF東京@秋葉原 UDXMarmalade/Cocos2d-x & Photon の最新事例

• 8/24-26 CEDEC 2016• その他も続々開催予定!

Photon SNS アカウント• Twitter– @PhotonCloudJP

• Facebook– https://www.facebook.com/photoncloudjp/

• ヘルプセンター– https://support.photonegine.jp/hc/ja

まとめ• Plugin はロジック組み込みを簡単にします!• Photon Enterprise Cloud は運用フリーで柔軟性の高いクラウドサービスです!• Photon Enterprise Cloud + Plugin は最強の組み合わせです!• Photon Server で Plugin も有効です!

ありがとうございました!develper@photonengine.jp

top related