SlideShare a Scribd company logo
1 of 176
Download to read offline
MagicOnion
〜C#でゲームサーバを開発しよう〜
.NET Conf in Tokyo 2019
#dotnetconfunity
2019/10/27
とりすーぷ
⾃⼰紹介
• 「とりすーぷ」
• @toRisouP
• 株式会社バーチャルキャスト 開発
• xR開発
• 最近はサーバ開発
• Microsoft MVP
for Developer Technologies 2018〜2020
今回の話
• MagicOnionについて解説
• 何のためのフレームワークか
• どんな機能があるのか
• 環境構築
• 実装例の紹介
• 実装時の注意点
• デプロイ
MagicOnionって何?
MagicOnion is 何
• ネットワーク通信のためのフレームワーク
• Unityでのゲーム開発を中⼼に使えるネットワーク通信フレームワーク
• サーバサイド:.NET Core
• クライアントサイド:Unity / .NET Core
• 開発はCysharp社
• MITライセンス
MagicOnionのバックエンド
• C# + .NET Core / Unity
• 通信プロトコル: gRPC
• データフォーマット: MessagePack for C#
• 定義したC#ファイルがそのままDSLになる
• C#インタフェースがAPIのエンドポイント
• C#オブジェクトが通信データ構造(MessagePackObject)
MagicOnionのバックエンド
クライアント サーバ
プロトコルはgRPC
データフォーマットはMessagePack C#ファイルの定義がそのままAPIのエンドポイントに
コード共有
• 定義したインタフェースやオブジェクトを、
サーバとクライアントで共有することで
そのままAPI定義として利⽤できる
コード共有
クライアント サーバ
インタフェース定義
(APIエンドポイント)
インタフェース定義されたC#ファイルを
クライアント・サーバで共有
例:APIエンド先⽃の定義
共有するインタフェースを定義
実装
クライアント サーバ
サーバ側はインタフェースを実装する
実装
サーバ側実装
呼び出し
クライアント サーバ
クライアント側はただ
インタフェースのメソッドを呼び出すだけ
メソッドコール
(async/awiat)
クライアント側の呼び出し
gRPCのコネクションを貼ってからメソッドを呼ぶだけ
インタフェースに定義されたメソッドをコール
裏で通信が⾏われ、結果はasync/awaitで待てる
サーバ処理の呼び出しの流れ
サーバ
メソッド実⾏すると裏でサーバコードが呼び出されて
その結果が返ってくるのをawaitで待てる
共有ファイルを介した通信
クライアント サーバ
共有したインタフェースを介して
クライアント/サーバ間の通信が可能になる
MagicOnion 最⼤の特徴
• 通信レイヤを意識せずにサーバコードを呼び出せる
• サーバとクライアントでC#インタフェースを共有すればOK
• 通信のデータ構造もC#で定義すればOK
• async/awaitでメソッド呼び出しするだけでサーバの処理を実⾏できる
• ただし、gRPCのコネクション管理だけは⾃前で管理しないとダメ(しょうがない)
MagicOnionの機能紹介
機能⼀覧
• 実装できるAPIの種類
• Service、StreamingHub
• Filter機能
• Filter
• その他便利な機能
• Swagger、Telemetry
APIの実装
• ⼤きく2つのAPI実装パターンがある
• Service
• StreamingHub
Service
• Service
• シンプルな単発のAPIを作成するのに使う
• 1Request ‒ 1Response通信(中⾝はUnary RPC)
• リクエストを投げた本⼈にのみレスポンスを返せる
Service
クライアント
サーバRequest
Response
1Requestに対して1Responseのみ返せるのが
「Service」で実装したAPI
StreamingHub
• StreamingHub
• リアルタイム通信向け
• 中⾝はBidirectional Streaming RPC
• 仮想的なコネクションを貼ったままずっと維持する
• クライアントとサーバが⾃由にメッセージを送受信できる
• 全体へブロードキャストも可能
StreamingHub
クライアント
サーバ
Message
クライアント同⼠がサーバを介して
相互通信できるのが「StremingHub」
Broadcast
Broadcast
機能⼀覧
• 実装できるAPIの種類
• Service、StreamingHub
• Filter機能
• Filter
• その他便利な機能
• Swagger、Telemetry
Filter
• 通信の前後に処理を追加する機能
• サーバ側フィルタ
• Service、StreamingHubに適⽤可能
• クライアント側フィルタ
• Serviceのみ対応
Filterの実装例(サーバ側)
Filterを反映する
• Filterを付けたいクラス/メソッドにAttributeをつける
• このメソッド/クラスのRPCが実⾏されるタイミングで、
定義したFilterを通過する
Filterの⽤途
• 使⽤例
• 認証⽤のヘッダーを追加
• メッセージの暗号化/復号化
• 通信ログ出⼒
• 通信をせずにダミーのレスポンスの差し替え
• エラーメッセージのハンドリング
• リトライ処理
機能⼀覧
• 実装できるAPIの種類
• Service、StreamingHub
• Filter機能
• Filter
• その他便利な機能
• Swagger、Telemetry
便利な機能
• Swagger対応
• 「Service」で実装したメソッドをREST APIとして実⾏できる
• Webブラウザ上でAPIの動作確認ができる
• デバッグに便利
• Telemetry対応
• MagicOnionの監視
• メトリクス
今回の話
• MagicOnionについて解説
• 何のためのフレームワークか
• どんな機能があるのか
• 環境構築
• 実装例の紹介
• 実装時の注意点
• デプロイ
MagicOnionの環境構築
環境構築
• MagicOnionは環境構築がちょっとたいへん
• クライアント側(Unity)は⼿動でライブラリ追加が必要
• コード共有
• コードジェネレート
クライアント ライブラリ導⼊
• これらのライブラリを⼿動でUnityに導⼊する必要がある
• MagicOnion.Client.Unity.unitypackage
• https://github.com/Cysharp/MagicOnion/releases
• MessagePack.Unity.x.x.x.x.unitypackage
• https://github.com/neuecc/MessagePack-CSharp/releases
• gRPC Unity plugin
• https://packages.grpc.io/
Player Settingsも設定が必要
• Scripting Define Symbols
• ENABLE_UNSAFE_MSGPACK を書き⾜す
• Allow ʻunsafeʼ Code
• Enable
ついでに導⼊するとよさげ
• UniRx
• Reactive Extensions for Unity
• イベント処理の整理に便利
• UniTask
• ValueTask for Unity
• Unity向けのAwaiter実装の提供
• ⾮同期周りにはコレ
環境構築
• MagicOnionは環境構築がちょっとたいへん
• クライアント側(Unity)は⼿動でライブラリ追加が必要
• コード共有
• コードジェネレート
コード共有について
クライアント サーバ
インタフェース定義
(APIエンドポイント)
インタフェース定義されたC#ファイルを
どうやってクライアント/サーバでコード共有するの?
Unity側の制約
• C#コードはAssets/以下に配置しないといけない
• UnityはAssets/以下のC#ファイルしかコンパイルしてくれない
オススメの⽅法
• サーバ側のcsprojからUnity/Assets以下を参照する
• 実体はUnity側にあり、それをサーバプロジェクトで開いているだけ
参照
Unityサーバプロジェクト
プロジェクト構成の例
Assets/
Assets/Shared/
サーバプロジェクト(ソリューション構成)
Server.Interfaces.csproj Server.Core.csproj
プロジェクト構成の⼀例
プロジェクト構成の例
Assets/
Assets/Shared/
サーバプロジェクト(ソリューション構成)
Server.Interfaces.csproj Server.Core.csproj
共有⽤csprojからUnity/Assets/以下を参照する
参照
ファイルの実体はこっち
プロジェクト構成の例
Assets/
Assets/Shared/
サーバプロジェクト(ソリューション構成)
Server.Interfaces.csproj Server.Core.csproj
ポイント:共有するcsprojと、サーバのコアロジックのcsprojを分離して
コアプロジェクトから共有プロジェクトを参照する
参照
プロジェクト構成の例
Assets/
Assets/Shared/
Server.Interfaces.csproj Server.Core.csproj
git管理するときはこれらをまとめて1つのリポジトリに⼊れる
これで1つの Git Repository
この⽅法のメリット
• 設定が簡単
• csprojに数⾏書き⾜すだけで設定が終わる
• リポジトリをチェックアウトしてくればそのまま動く
• 環境に依存しない
• シンボリックリンクとかそういう⾯倒な作業もいらない
• 相対パスさえ維持されていれば動く
デメリット
• リポジトリが1個にまとまってしまう
• サーバのビルドにクライアントコードのcheckoutも必要になる
• クライアントの容量が⼤きくなってくるとCI/CDがツライことになる
• 開発フローの整理が難しくなる
• クライアント開発とサーバ開発が同じリポジトリで管理される
• GitHubのissue/pr 欄が混ざる
折半案
サーバ側
サーバプロジェクトのポジトリ
Git Repository
Git Repository
ゲーム本体のリポジトリ
折半案
サーバ側
ここのUnityプロジェクトは、
Headlessなクライアント + Debug Scene
が置かれる
Git Repository
Git Repository
折半案
サーバ側
ゲーム本体のプロジェクトは
別のリポジトリとして運⽤する
折半案
サーバ側
接続部分をunitypackageにまとめて
本体側でインポートする
unitypackage
補⾜:UnityPackageはどう管理する?
• Unity Package Managerで管理できる
• Unity標準のパッケージマネージャ機能
• まだ発展途上
• ⾃前でレジストリを⽴てればオレオレライブラリも管理可能
• 余⼒があるならコレで管理すると良さそう
環境構築
• MagicOnionは環境構築がちょっとたいへん
• クライアント側(Unity)は⼿動でライブラリ追加が必要
• コード共有
• コードジェネレート
コードジェネレートの話
• MagicOnionの動作にはコードジェネレートが2回必要
• MagicOnionのインタフェース定義
• MessagePackのオブジェクト定義
• ただし、ジェネレートが必要なのはUnity側のみ(サーバ側は不要)
• ジェネレートしたコードはUnityプロジェクトに配置する
ジェネレータの⽤意
• それぞれGitHubからダウンロードできる
MagicOnion MessagePack
ジェネレータの使い⽅
• 対象のcsprojをコマンドラインで指定して実⾏
• MagicOnnion/MessagePack共に同じコマンド引数で動く
指定するcsproj
• 共有するインタフェースとオブジェクトが含まれたもの
• 共有するファイルだけまとめたcsprojを⽤意しておくと楽
指定するcsprojの例
Assets/
Assets/Shared/
サーバプロジェクト(ソリューション構成)
Server.Interfaces.csproj Server.Core.csproj
これ!
注意点
• ジェネレート対象のcsprojがMagicOnionとMessagePack
に依存するようにしておくこと
• 依存させておかないとコードジェネレートが動かない
Server.Interfaces.csproj
コマンド例
./moc/win-x64/moc.exe
‒i ./Server/ServerSample.Interfaces/ServerSample.Interfaces.csproj
‒o ./Unity/Assets/Scripts/Generated/MagicOnion.Generated.cs
• MagicOnionのジェネレート例
• ServerSample.Interfaces.csprojをもとに、Unity/Assets/以下に⽣成
MessagePackのResolver設定だけ忘れずに
• Unityプロジェクトに次のようなコードを配置
• RuntimeInitializeOnLoadMethodで起動時に実⾏されるようにしておく
Editor拡張でジェネレートできると楽
• MagicOnionのサンプルコードに実装例がある
• https://github.com/Cysharp/MagicOnion/blob/master
/samples/ChatApp/ChatApp.Unity/Assets/Editor/MenuItems
.cs
環境構築 まとめ
• 環境構築がちょっと⼤変
• csprojを編集する必要がある
• コードジェネレートの整備が⼿間
• 開発フローはよく考えよう
• Unity側とサーバ側、2つのプロジェクト管理を同時にやる必要
• gitリポジトリをどうわけるか、どういうフローで開発をすすめるのか
• CI/CDとの相性
今回の話
• MagicOnionについて解説
• 何のためのフレームワークか
• どんな機能があるのか
• 環境構築
• 実装例の紹介
• 実装時の注意点
• デプロイ
実装例の紹介
実装例
• それぞれの実装例を紹介
• Service
• StreamingHub
Serviceの実装例
• サーバサイドで⾜し算する
• シンプルに、引数に与えた数値を⾜して返す
Serviceの実装例
• 実装⼿順
1. 共有するインタフェース/オブジェクトを定義
2. サーバに実装を書く
3. サーバにコネクションする
4. Unity側で呼び出す
Serviceの実装例
• 実装⼿順
1. 共有するインタフェース/オブジェクトを定義
2. サーバに実装を書く
3. サーバにコネクションする
4. Unity側で呼び出す
指定するcsprojの例
Assets/
Assets/Shared/
サーバプロジェクト(ソリューション構成)
Server.Interfaces.csproj Server.Core.csproj
ここに定義する
(どっちに定義しても実体は1個なので同じ)
Service:サーバサイドで計算する
1.サーバ/クライアントで共有するインタフェースを⽤意
IService<T>を継承したインタフェースを定義する
インタフェース内に定義したメソッドがAPIエンドポイントになる
Serviceの実装例
• 実装⼿順
1. 共有するインタフェース/オブジェクトを定義
2. サーバに実装を書く
3. サーバにコネクションする
4. Unity側で呼び出す
指定するcsprojの例
Assets/
Assets/Shared/
サーバプロジェクト(ソリューション構成)
Server.Interfaces.csproj Server.Core.csproj
ここに定義する
例:サーバサイドで計算する
2.サーバ側で実装を⾏う
インタフェースを実装
今回は引数を⾜して返すだけ
Serviceの実装例
• 実装⼿順
1. 共有するインタフェース/オブジェクトを定義
2. サーバに実装を書く
3. サーバにコネクションする
4. Unity側で呼び出す
例:サーバサイドで計算する
3. サーバにコネクションする
gRPCのチャンネルを作って
例:サーバサイドで計算する
4. Unity側で呼び出す
ICalculateServiceへのクライアントを作り
例:サーバサイドで計算する
4. Unity側で呼び出す
あとは普通にメソッドコールするだけ
通信の結果はasync/awaitで待つだけでOK
例:サーバサイドで計算する
サーバ
メソッド実⾏すると裏でサーバコードが呼び出されて
その結果が返ってくるのをawaitで待てる
Serviceの実装は簡単
• リクエストに対して、処理を書いて、結果を返すだけ
• かんたん
• クライアント側は普通にasync/awaitでメソッドを呼ぶだけ
• サーバ側はインタフェースを実装するだけ
StreamingHubの実装例
StreamingHubはムズカシイ
• StreamingHubはリアルタイム通信を実現する機構
• クライアントとサーバが相互にメソッドを呼び出し合える
• Serviceの実装と⽐べて複雑になりやすい
• 「状態」がクライアントとサーバの両⽅で管理することになる
• どのタイミングで何の処理が実⾏されるか、を整理しないとヤバイことになる
StreamingHubの実装例
• サーバサイドでPlayerとその座標を管理する
• Playerは移動量をサーバに送って、移動先を更新する
• Playerが移動したら全員に通知する
• ⼊室時に既存のPlayer⼀覧を返す
• Playerが⼊室/退室したら通知する
• 単⼀のプロセスでのみ動く(プロセス間での協調は考えない)
動作例
クライアントA
サーバ
クライアントがサーバにコネクションしている
クライアントB
動作例
クライアントA
サーバ
サーバ側で座標⼀覧を管理
クライアントB A: (1, 0 ,0 )
B: (0, 0, 2 )
動作例
クライアントA
サーバ
MoveAsync()をクライアントがコールすると
サーバ上の状態が書き換わり
クライアントB A: (1 +1, 0 +0 ,0 +0 )
B: (0, 0, 2 )
MoveAsync( +1, +0, +0)
動作例
クライアントA
サーバ
新しい座標を全員に通知する
クライアントB A: (1, 0 ,0 )
B: (0, 0, 2 )
OnPlayerMoved( id: A, position: (1,0,0) )
OnPlayerMoved( id: A, position: (1,0,0) )
動作例
クライアントA
サーバ
新しいクライアントが接続してきたら
サーバ側で新しいPlayerIdを発⾏して返す
クライアントB A: (1, 0 ,0 )
B: (0, 0, 2 )
C: (0, 0, 0)
クライアントC
Task<int> JoinAsync()
=> id: 12345
動作例
クライアントA
サーバ
既存のクライアントにPlayer⼊室イベントを送信する
クライアントB A: (1, 0 ,0 )
B: (0, 0, 2 )
C: (0, 0, 0)
クライアントC
OnPlayerJoined( id: 12345, position: (0,0,0) )
OnPlayerJoined( id: 12345, position: (0,0,0) )
動作例
クライアントA
サーバ
クライアントCが既存のPlayerの状態⼀覧を
サーバから取得して状態を再現する
クライアントB A: (1, 0 ,0 )
B: (0, 0, 2 )
C: (0, 0, 0)
クライアントC Task<PlayerStatus[]>
FetchCurrentAsync()
A: (1, 0 ,0 )
B: (0, 0, 2 )
C: (0, 0, 0)
動作例
実装順序
• 実装順序
1. インタフェース定義
2. 通信のオブジェクト定義
3. サーバ側実装
4. クライアント側実装
例:座標管理
1. インタフェース定義
• 定義するインタフェースは2つある
• サーバ → クライアント(Receiver)
• クライアント → サーバ(Hub)
1.インタフェース定義(Receiver)
• サーバ→クライアント(Receiver)
• クライアントで実装するメソッド
• サーバから呼び出される
1.インタフェース定義(Hub)
• クライアント→サーバ(Hub)
• サーバで実装するメソッド
• クライアントが呼び出す
2.通信のオブジェクト定義
• 通信に利⽤するデータ構造を定義する
• MessagePackObjectとして定義する
• (定義したあとはMessagePackのコードジェネレートが必要)
2.通信⽤オブジェクトの定義
• 「プレイヤの状態」を扱うデータ構造
2.通信⽤オブジェクトの定義
• 「プレイヤの状態」を扱うデータ構造
サーバサイドは「MessagePack.UnityShims」を導⼊すると
Unityのデータ構造がそのまま使えて便利
3.サーバ側の実装
• StreamingHubの特性を覚えよう
• 1コネクションごとに新しいインスタンスが⽣成して割り当てられる
• コネクションが維持されている限り同じインスタンスが使われる
(インメモリで状態が保持され続ける)
StreamingHubの図
サーバプロセス
StreamingHub
StreamingHub
StreamingHub
クライアント
Application
Application
Service
1コネクションごとにStreamingHubの
インスタンスが⽣成されて、それが維持される
Domain
Application
Domain
Application
Service
StreamingHubの図
サーバプロセス
StreamingHub
StreamingHub
StreamingHub
クライアント
Hub間でデータを共有するなら、
Hubより後ろ側の実装でイイカンジに処理するとヨサソウ
今回の例
サーバプロセス
PlayerHub
PlayerHub
PlayerHub
クライアント
PlayerManager
今回はレイヤ構造を作らずにシンプルな形でつくる
(本当はクリーンアーキテクチャとかに則った⽅がいい)
インメモリでPlayerの状態を
保持するオブジェクト
3.サーバ側の実装
• PlayerManager
• Playerの状態をインメモリで管理するシングルトンなオブジェクト
• 各Hubのインスタンスが同時にアクセスするオブジェクトなので、
中⾝の実装はThread Safeにつくる必要がある
3.サーバ側の実装
• PlayerHub 1/5
• コンストラクタ
3.サーバ側の実装
• PlayerHub 1/5
• コンストラクタ
インメモリで状態を保持できる
3.サーバ側の実装
• PlayerHub 1/5
• コンストラクタ
PlayerManagerはDIで渡される
3.サーバ側の実装
• PlayerHub 2/5
• 新規参加処理「JoinAsync()」
3.サーバ側の実装
• PlayerHub 2/4
• 新規参加処理「JoinAsync()」
1. 新しいPlayerをPlayerManagerに作ってもらう
2. このHubをGroupに登録
3. 既存のクライアントにメッセージ発⾏ & My IDをreturn
3.サーバ側の実装
• PlayerHub 2/4
• 新規参加処理「JoinAsync()」
1. 新しいPlayerをPlayerManagerに作ってもらう
2. このHubをGroupに登録
3. 既存のクライアントにメッセージ発⾏ & My IDをreturn
3.サーバ側の実装
• PlayerHub 2/4
• 新規参加処理「JoinAsync()」
1. 新しいPlayerをPlayerManagerに作ってもらう
2. このHubをGroupに登録
3. 既存のクライアントにメッセージ発⾏ & My IDをreturn
3.サーバ側の実装
• PlayerHub 2/4
• 新規参加処理「JoinAsync()」
1. 新しいPlayerをPlayerManagerに作ってもらう
2. このHubをGroupに登録
3. 既存のクライアントにメッセージ発⾏ & My IDをreturn
めっちゃ⼤事!!!
Group
• Hub同⼠を束ねる機能
• マッチングに合わせてHubをグルーピングする機能
• ⽂字列を指定してGroupに参加できる
• 同じGroup内にメッセージをまとめて発⾏(Broadcast)できる
StreamingHubの「Group」
サーバプロセス
PlayerHub
PlayerHub
PlayerHub
クライアント
メッセージのBroadcastは
同⼀GroupのHubにつないだクライアントに対して送ることができる
Group “A”
Group “A”
Group “B”
同じGroup内なら
メッセージが送れる
Groupはまたげない
Broadcast()
Broadcastの種類
• Broadcast(IGroup)
• 指定Group内の、クライアント全員に送信
• BroadcastToSelf(IGroup) / BroadcastExceptSelf(IGRoup)
• ⾃分に対してのみ送信 / ⾃分以外の全員に送信
• BroadcastExcept(IGRoup, Guid / Guid[])
• 指定Group内の、指定のクライアントを除く全員に送信
• BroadcastTo(IGRoup, Guid / Guid[])
• 指定Group内の、指定のクライアントのみへ送信
3.サーバ側の実装
• PlayerHub 2/5
• 新規参加処理「JoinAsync()」
今回はGroupは1つに固定
(参加したクライアントが全員同じ部屋にマッチングする)
3.サーバ側の実装
• PlayerHub 3/5
• 既存のPlayer情報を取得して返す
3.サーバ側の実装
• PlayerHub 4/5
• 移動処理
• 座標更新をしたあと、OnPlayerMovedメッセージをBroadcast
3.サーバ側の実装
• PlayerHub 5/5
• 切断処理
実装順序
• 実装順序
1. インタフェース定義
2. 通信のオブジェクト定義
3. サーバ側実装
4. クライアント側実装
4.クライアント側
• HubClientの⽣成
4.クライアント側
• 参加して既存Playerの状態復元
4.クライアント側
• 移動処理
• ⼊⼒があったらサーバのMoveAsync()を呼ぶ
4.クライアント側
• 移動コールバック
• サーバからPlayerの座標更新通知がくる
• メッセージをもとに、そのIDのPlayerの座標を更新(描画)
動作例
StreamingHubの実装
• Serviceより実装が複雑になりやすい
• どの状態を、誰が保持して、どこまで再現するのか?の管理が⼤変
• StreamingHubのインスタンスがステートフルである
• 後から接続したクライアントと既存のクライアントの同期をどこまで担保するか
• クライアントとサーバの実装が密結合化する
• データフロー、ロジックの流れを精査しないとグチャグチャになる
• ドメインイベントを起因にしてメッセージを発⾏するスタイルがゴチャらなさそう
「実装例の紹介」のまとめ
• Serviceの実装は、かんたん
• REST APIのControllerを作るのと⼤差ない
• Filterと合わせると便利
• StreamingHubは、表現⼒が⾼いがムズカシイ
• なんでもできそうな代わりに、整えるのが難しい
• バックエンド側のアーキテクチャをかなり考える必要あり
今回の話
• MagicOnionについて解説
• 何のためのフレームワークか
• どんな機能があるのか
• 環境構築
• 実装例の紹介
• 実装時の注意点
• デプロイ
実装時の注意点
覚えておくといいテクニックとか
• クライアント側
• gRPCのコネクション管理ちゃんとやろう
• サーバ側
• Server GC使おう
• ThreadPoolのサイズを増やそう
• Generic Host使おう
クライアント側
• gRPCのコネクション管理を気をつけよう
gRPCのコネクション管理
• C#のgRPC Client(Channel)はUnmanaged
• Channelを利⽤している部分のDisposeを忘れるとすぐリークする
• Dispose漏れがある状態でコネクションを閉じようとすると、やばい
• Unity Editorごと巻き込んでフリーズしたり、アプリが正しく終了できなかったり
MagicOnionの場合は、MagicOnion ClientのDisposeを必ず呼ぶこと
管理する機構を作るとヨサソウ
• マネージャをDisposeしたら関連するClientもまとめて
Disposeする、みたいな機構を⽤意しておくとよさそう
希望の光
• マネージドgRPCクライアント「grpc-dotnet」
• .NET Core 3.0向け
• Unityではまだ使えない
• 今後に期待
サーバ側
• Server GCを使おう
• ThreadPoolのサイズを増やそう
• Generic Hostを使おう
Server GC
• C#のGCモードを「Server」に切り替えよう
• Background garbage collectionが有効になる
• CPUリソースの消費量が増える代わりに、Stop-the-worldが短くなる
設定⽅法
• csprojに下記を追加
• ServerGarbageCollection = true
覚えておくといいこと(サーバ)
• Server GCを使おう
• ThreadPoolのサイズを増やそう
• Generic Hostを使おう
ThreadPoolのサイズ
• C#のThreadPoolの拡張速度は遅い
• スループットを上げるにはあらかじめ⼤きめにしておくと良い
(最⼤1000まで、デフォルト値は25)
覚えておくといいこと(サーバ)
• Server GCを使おう
• ThreadPoolのサイズを増やそう
• Generic Hostを使おう
Generic Host
• ASP.NETから汎⽤機能を分離した公式フレームワーク
• メッセージング
• バックグラウンドサービスの起動
• 依存関係の注⼊(DI)
• ロギング
• 設定ファイル(config)の読み込み
• サーバアプリケーションで必須な機能をまとめた便利パッケージ
MagicOnion on GenericHost
• 「MagicOnion.Hosting」パッケージを追加すればOK
• あとは起動処理をGenericHost⾵にすればOK
Configファイルの読み込み設定
・./config/local.jsonの読み込み
・環境変数のバインド
・起動時のコマンドライン引数の読み込み
DIの設定
・PlayerManager をSingletonとしてBind
ログの設定
・コンソールにログを流す
MagicOnionの起動設定
例:Configの読み込み
• Jsonファイルを配置して読み込み設定を書いておけば
./config/local.json
DIでConfigオブジェクトが渡される
Logging
• ILogger<T>をDIして使う
実装の注意点 まとめ
• gPRCのコネクション管理はマジで気をつけよう
• 切断時の処理とか再接続とか考えると頭痛いけどガンバッテ…
• Generic Hostを使おう
• コレいれておけば雑務な部分は全部やってくれる
• 既存のASP.NETの資産がそのまま流⽤できて便利
今回の話
• MagicOnionについて解説
• 何のためのフレームワークか
• どんな機能があるのか
• 環境構築
• 実装例の紹介
• 実装時の注意点
• デプロイ
MagicOnionのデプロイ
デプロイ
• どういう構成で、どこで、どうやって動かす?
• どこでビルドするの
• どこでどう動かすの
• MagicOnionのサーバ構成
デプロイ
• どういう構成で、どこで、どうやって動かす?
• どこでビルドするの
• どこでどう動かすの
• MagicOnionのサーバ構成
どうするの
• サーバで動かすならDockerビルドしよう
• ビルドするならCircle CIが便利
• Kubernetesでコンテナ管理がよさ
• もちろんコレ以外のやり⽅でもできるけど、多分コレが⼀番無難な選択だと思う
Kubernetes
• Dockerコンテナのオーケストレーションツール
• インフラ構成をyamlファイルで管理できる便利システム
• yamlにどのマシン(Node)に、何のコンテナをどう起動するか(Pod)を書いて
applyすればそのとおりにコンテナが起動してくれる
• 開発元はGoogle
• 現状、Dockerのデファクトスタンダード
• AWS、GCP、Azureももちろん対応している
デプロイ
• どういう構成で、どこで、どうやって動かす?
• どこでビルドするの
• どこでどう動かすの
• MagicOnionのサーバ構成
MagicOnionのサーバ構成
• ⼤きく分けて2つの構成が選べる
• ステートフル構成
• ステートレス構成
• それぞれ⼀⻑⼀短ある
ステートフル構成
• プロセス側で状態を保持する構成
• 簡単にいうと「インメモリでデータを保持する」実装
• あるGroupに参加したいならそのGroupの状態を持っている
インスタンスを選んで接続する必要がある
ステートフル構成
MagicOnionインスタンス(サーバプロセス)
StreamingHub
クライアント
各インスタンスに対応するGroupが決まっている
Group “A”
StreamingHub
StreamingHub
StreamingHub
StreamingHub
Group “B”
Group “C”
状態(インメモリ)
インスタンス X
AとBを担当
インスタンス Y
Cを担当
ステートフル構成
MagicOnionインスタンス(サーバプロセス)
StreamingHub
クライアント
新しいクライアントがつなぐ場合は、
接続したいGroupに合わせてインスタンスを選択する必要がある
StreamingHub
StreamingHub
StreamingHub
StreamingHub
状態(インメモリ)
インスタンス X
AとBを担当
インスタンス Y
Cを担当
新しい
クライアント
「Bに⼊りたいから
Xにつなぐ!」
ステートフル構成
• メリット
• リアルタイム通信に向く
• ⼤量のメッセージのBroadcastがプロセス内で完結する
• データの保持もインメモリで済む
• 外部ストレージへのトランザクション処理が省略できる
• インメモリで済む限りにおいて、外部ストレージを使わないので⾼速に処理可能
ステートフル構成
• デメリット
• オートスケールしにくい、LBが使えない、停⽌メンテが必要になるかも
• ステートフルなのでプロセスをいきなり落とすと死ぬ
• LBの代わりに、サービスディスカバリの⽤意が必要
• Kubernetesと相性が悪い
• External IP / Node Portの設定をがんばる必要がある
• Agonesが使えたらマシになりそう
サービスディスカバリ
• 「ホスト」と「インスタンス」の割当を管理するシステム
インスタンス X インスタンス Y
Service Discovery
インスタンスが保持する
Groupの情報を同期
10.0.0.5:12345 10.0.0.6:12345
サービスディスカバリ
• 「ホスト」と「インスタンス」の割当を管理するシステム
インスタンス X インスタンス Y
Service Discovery
10.0.0.5:12345 10.0.0.6:12345
「 に繋ぎたい」
「10.0.0.5:12345につないでね」
Agones
• GoogleとUbisoftが共同で開発している
マルチプレイヤーゲーム向けのサーバ管理システム
• Kubernetesと協調して動く
• マッチングに合わせてコンテナの起動、接続、停⽌を管理してくれる
• OSS
• 2019年9⽉にv1.0.0が出たばかり
• Ubisoftが使っていた実績はあるが、巷に知⾒があまりない
• 興味がある⼈は⼿を出すとよさそう
ステートレス構成
• プロセス上に状態を持たない構成
• MagicOnionのプロセス同⼠がバックエンドで協調して動く
• どのインスタンスにつないでも好きなGroupに参加できる
ステートレス構成
MagicOnionクライアント
クライアントはMagicOnionのホストがどうなっているかを
意識せずにすきなGroupに参加できる
Group “A”
Group “B”
Group “C”
RedisGroup “B”
Group “A”
Group “A”
Group “C”
Load Balancer
MagicOnionのメッセージは
Redis pub/sub経由でBroadcast
ステートレス構成にするには
• バックエンドにRedisが必要
• Redis Clusterをバックエンドに組む必要がある
• MagicOnionに追加のパッケージが必要
• 「MagicOnion.Redis」を追加
ステートレス構成
• メリット
• オートスケーリングができる
• Load Balancerで負荷分散できる
• ローリングアップデートしやすい
• Kubernetesもニッコリ
ステートレス構成
• デメリット
• リアルタイム通信に向いてない
• メッセージのBroadcastにプロセスをまたぐ必要がある
• データストレージへのトランザクション管理
• パフォーマンスがRedis依存
• MagicOnionがバックエンドにRedis pub/subを利⽤するため
• Redis Clusterを組んでてもpub/subの性能はさほど向上しない
• ⼤規模になるとここが⼀番ツライことになる
構成についてのまとめ
• リアルタイム通信なら「ステートフル」のほうがオススメ
• ただしKubernetes周りが結構キビシイ
• Agonesなんとかしてくれー!!!
• サービスディスカバリは⾃前で作るのがヨサソウ
まとめ
MagicOnionについてのまとめ
• サーバサイドもC#で「いい感じ」にサーバが作れる
• ゲーム向けのリアルタイム通信⽤途にも耐えうる
• クライアントとサーバをC#で統⼀できる
• クライアントエンジニアをそのままサーバ開発に回せる
• 最新のC#を使える!楽しい!
ただし…
• 開発フローの整備が課題
• クライアントとサーバがかなり密結合する
• プロジェクト全体でフローを決めないと混乱しそう
• サーバサイドの開発知識はある程度必要
• クライアントエンジニアを即⽇でサーバ開発に回すのはキビシイ
• ある程度のスイッチングコストは⾒越しておくべき
総評
• 「MagicOnioは、いいぞ。」
• サーバサイドもC#で書けるのは、結構気持ちいい(個⼈の感想)
• クライアントとサーバの開発の境⽬がなくなる
• MagicOnionというか、Kubernetesの運⽤の⽅がムズい
• Agonesに期待

More Related Content

What's hot

Unity C#と.NET Core(MagicOnion) C# そしてKotlinによるハーモニー
Unity C#と.NET Core(MagicOnion) C# そしてKotlinによるハーモニーUnity C#と.NET Core(MagicOnion) C# そしてKotlinによるハーモニー
Unity C#と.NET Core(MagicOnion) C# そしてKotlinによるハーモニーYoshifumi Kawai
 
Unityでオンラインゲーム作った話
Unityでオンラインゲーム作った話Unityでオンラインゲーム作った話
Unityでオンラインゲーム作った話torisoup
 
UniTask入門
UniTask入門UniTask入門
UniTask入門torisoup
 
Unity開発で使える設計の話+Zenjectの紹介
Unity開発で使える設計の話+Zenjectの紹介Unity開発で使える設計の話+Zenjectの紹介
Unity開発で使える設計の話+Zenjectの紹介torisoup
 
コールバックと戦う話
コールバックと戦う話コールバックと戦う話
コールバックと戦う話torisoup
 
RPGにおけるイベント駆動型の設計と実装
RPGにおけるイベント駆動型の設計と実装RPGにおけるイベント駆動型の設計と実装
RPGにおけるイベント駆動型の設計と実装Koji Morikawa
 
Unityネットワーク通信の基盤である「RPC」について、意外と知られていないボトルネックと、その対策法
Unityネットワーク通信の基盤である「RPC」について、意外と知られていないボトルネックと、その対策法Unityネットワーク通信の基盤である「RPC」について、意外と知られていないボトルネックと、その対策法
Unityネットワーク通信の基盤である「RPC」について、意外と知られていないボトルネックと、その対策法モノビット エンジン
 
ネットワーク ゲームにおけるTCPとUDPの使い分け
ネットワーク ゲームにおけるTCPとUDPの使い分けネットワーク ゲームにおけるTCPとUDPの使い分け
ネットワーク ゲームにおけるTCPとUDPの使い分けモノビット エンジン
 
C# ゲームプログラミングはホントにメモリのことに無頓着でいいの?
C# ゲームプログラミングはホントにメモリのことに無頓着でいいの?C# ゲームプログラミングはホントにメモリのことに無頓着でいいの?
C# ゲームプログラミングはホントにメモリのことに無頓着でいいの?京大 マイコンクラブ
 
リアルタイムサーバー 〜Erlang/OTPで作るPubSubサーバー〜
リアルタイムサーバー 〜Erlang/OTPで作るPubSubサーバー〜 リアルタイムサーバー 〜Erlang/OTPで作るPubSubサーバー〜
リアルタイムサーバー 〜Erlang/OTPで作るPubSubサーバー〜 Yugo Shimizu
 
Unityでパフォーマンスの良いUIを作る為のTips
Unityでパフォーマンスの良いUIを作る為のTipsUnityでパフォーマンスの良いUIを作る為のTips
Unityでパフォーマンスの良いUIを作る為のTipsUnity Technologies Japan K.K.
 
【Unite 2018 Tokyo】そろそろ楽がしたい!新アセットバンドルワークフロー&リソースマネージャー詳細解説
【Unite 2018 Tokyo】そろそろ楽がしたい!新アセットバンドルワークフロー&リソースマネージャー詳細解説【Unite 2018 Tokyo】そろそろ楽がしたい!新アセットバンドルワークフロー&リソースマネージャー詳細解説
【Unite 2018 Tokyo】そろそろ楽がしたい!新アセットバンドルワークフロー&リソースマネージャー詳細解説Unity Technologies Japan K.K.
 
ゲーム開発とデザインパターン
ゲーム開発とデザインパターンゲーム開発とデザインパターン
ゲーム開発とデザインパターンTakashi Komada
 
UniRx完全に理解した
UniRx完全に理解したUniRx完全に理解した
UniRx完全に理解したtorisoup
 
Observableで非同期処理
Observableで非同期処理Observableで非同期処理
Observableで非同期処理torisoup
 
Unity 2018-2019を見据えたDeNAのUnity開発のこれから [DeNA TechCon 2019]
Unity 2018-2019を見据えたDeNAのUnity開発のこれから [DeNA TechCon 2019]Unity 2018-2019を見据えたDeNAのUnity開発のこれから [DeNA TechCon 2019]
Unity 2018-2019を見据えたDeNAのUnity開発のこれから [DeNA TechCon 2019]DeNA
 
スマホゲームのチート手法とその対策 [DeNA TechCon 2019]
スマホゲームのチート手法とその対策 [DeNA TechCon 2019]スマホゲームのチート手法とその対策 [DeNA TechCon 2019]
スマホゲームのチート手法とその対策 [DeNA TechCon 2019]DeNA
 
200人での対戦も可能!?Photon 新SDKについて
200人での対戦も可能!?Photon 新SDKについて200人での対戦も可能!?Photon 新SDKについて
200人での対戦も可能!?Photon 新SDKについてPhoton運営事務局
 

What's hot (20)

Unity C#と.NET Core(MagicOnion) C# そしてKotlinによるハーモニー
Unity C#と.NET Core(MagicOnion) C# そしてKotlinによるハーモニーUnity C#と.NET Core(MagicOnion) C# そしてKotlinによるハーモニー
Unity C#と.NET Core(MagicOnion) C# そしてKotlinによるハーモニー
 
Unityでオンラインゲーム作った話
Unityでオンラインゲーム作った話Unityでオンラインゲーム作った話
Unityでオンラインゲーム作った話
 
UniTask入門
UniTask入門UniTask入門
UniTask入門
 
Unity開発で使える設計の話+Zenjectの紹介
Unity開発で使える設計の話+Zenjectの紹介Unity開発で使える設計の話+Zenjectの紹介
Unity開発で使える設計の話+Zenjectの紹介
 
コールバックと戦う話
コールバックと戦う話コールバックと戦う話
コールバックと戦う話
 
RPGにおけるイベント駆動型の設計と実装
RPGにおけるイベント駆動型の設計と実装RPGにおけるイベント駆動型の設計と実装
RPGにおけるイベント駆動型の設計と実装
 
Unityネットワーク通信の基盤である「RPC」について、意外と知られていないボトルネックと、その対策法
Unityネットワーク通信の基盤である「RPC」について、意外と知られていないボトルネックと、その対策法Unityネットワーク通信の基盤である「RPC」について、意外と知られていないボトルネックと、その対策法
Unityネットワーク通信の基盤である「RPC」について、意外と知られていないボトルネックと、その対策法
 
ネットワーク ゲームにおけるTCPとUDPの使い分け
ネットワーク ゲームにおけるTCPとUDPの使い分けネットワーク ゲームにおけるTCPとUDPの使い分け
ネットワーク ゲームにおけるTCPとUDPの使い分け
 
C# ゲームプログラミングはホントにメモリのことに無頓着でいいの?
C# ゲームプログラミングはホントにメモリのことに無頓着でいいの?C# ゲームプログラミングはホントにメモリのことに無頓着でいいの?
C# ゲームプログラミングはホントにメモリのことに無頓着でいいの?
 
リアルタイムサーバー 〜Erlang/OTPで作るPubSubサーバー〜
リアルタイムサーバー 〜Erlang/OTPで作るPubSubサーバー〜 リアルタイムサーバー 〜Erlang/OTPで作るPubSubサーバー〜
リアルタイムサーバー 〜Erlang/OTPで作るPubSubサーバー〜
 
Unityでパフォーマンスの良いUIを作る為のTips
Unityでパフォーマンスの良いUIを作る為のTipsUnityでパフォーマンスの良いUIを作る為のTips
Unityでパフォーマンスの良いUIを作る為のTips
 
Riderはいいぞ!
Riderはいいぞ!Riderはいいぞ!
Riderはいいぞ!
 
【Unite 2018 Tokyo】そろそろ楽がしたい!新アセットバンドルワークフロー&リソースマネージャー詳細解説
【Unite 2018 Tokyo】そろそろ楽がしたい!新アセットバンドルワークフロー&リソースマネージャー詳細解説【Unite 2018 Tokyo】そろそろ楽がしたい!新アセットバンドルワークフロー&リソースマネージャー詳細解説
【Unite 2018 Tokyo】そろそろ楽がしたい!新アセットバンドルワークフロー&リソースマネージャー詳細解説
 
ゲーム開発とデザインパターン
ゲーム開発とデザインパターンゲーム開発とデザインパターン
ゲーム開発とデザインパターン
 
多機能ボイチャを簡単に導入する方法
多機能ボイチャを簡単に導入する方法多機能ボイチャを簡単に導入する方法
多機能ボイチャを簡単に導入する方法
 
UniRx完全に理解した
UniRx完全に理解したUniRx完全に理解した
UniRx完全に理解した
 
Observableで非同期処理
Observableで非同期処理Observableで非同期処理
Observableで非同期処理
 
Unity 2018-2019を見据えたDeNAのUnity開発のこれから [DeNA TechCon 2019]
Unity 2018-2019を見据えたDeNAのUnity開発のこれから [DeNA TechCon 2019]Unity 2018-2019を見据えたDeNAのUnity開発のこれから [DeNA TechCon 2019]
Unity 2018-2019を見据えたDeNAのUnity開発のこれから [DeNA TechCon 2019]
 
スマホゲームのチート手法とその対策 [DeNA TechCon 2019]
スマホゲームのチート手法とその対策 [DeNA TechCon 2019]スマホゲームのチート手法とその対策 [DeNA TechCon 2019]
スマホゲームのチート手法とその対策 [DeNA TechCon 2019]
 
200人での対戦も可能!?Photon 新SDKについて
200人での対戦も可能!?Photon 新SDKについて200人での対戦も可能!?Photon 新SDKについて
200人での対戦も可能!?Photon 新SDKについて
 

Similar to MagicOnion~C#でゲームサーバを開発しよう~

Magic Leap で WebRTC 触ってみた
Magic Leap で WebRTC 触ってみたMagic Leap で WebRTC 触ってみた
Magic Leap で WebRTC 触ってみたNishoMatsusita
 
Dapr × Kubernetes ではじめるポータブルなマイクロサービス(CloudNative Days Tokyo 2020講演資料)
Dapr × Kubernetes ではじめるポータブルなマイクロサービス(CloudNative Days Tokyo 2020講演資料)Dapr × Kubernetes ではじめるポータブルなマイクロサービス(CloudNative Days Tokyo 2020講演資料)
Dapr × Kubernetes ではじめるポータブルなマイクロサービス(CloudNative Days Tokyo 2020講演資料)NTT DATA Technology & Innovation
 
Introduction to NetOpsCoding
Introduction to NetOpsCodingIntroduction to NetOpsCoding
Introduction to NetOpsCodingTaiji Tsuchiya
 
【Unity道場京都スペシャル4】Unityによるリアルタイム通信とMagicOnionによるC#大統一理論の実現
【Unity道場京都スペシャル4】Unityによるリアルタイム通信とMagicOnionによるC#大統一理論の実現【Unity道場京都スペシャル4】Unityによるリアルタイム通信とMagicOnionによるC#大統一理論の実現
【Unity道場京都スペシャル4】Unityによるリアルタイム通信とMagicOnionによるC#大統一理論の実現UnityTechnologiesJapan002
 
IoTと業務システムをつなぐgRPC/RESTサービスの開発と運用
IoTと業務システムをつなぐgRPC/RESTサービスの開発と運用IoTと業務システムをつなぐgRPC/RESTサービスの開発と運用
IoTと業務システムをつなぐgRPC/RESTサービスの開発と運用DeNA
 
SORACOM Conference "Discovery" 2018 | F3. SORACOMで実現する “Intranet” Of Things バ...
SORACOM Conference "Discovery" 2018 | F3. SORACOMで実現する “Intranet” Of Things バ...SORACOM Conference "Discovery" 2018 | F3. SORACOMで実現する “Intranet” Of Things バ...
SORACOM Conference "Discovery" 2018 | F3. SORACOMで実現する “Intranet” Of Things バ...SORACOM,INC
 
TypeScriptへの入口
TypeScriptへの入口TypeScriptへの入口
TypeScriptへの入口Sunao Tomita
 
Azure Antenna AI 概要
Azure Antenna AI 概要Azure Antenna AI 概要
Azure Antenna AI 概要Miho Yamamoto
 
試して学べるクラウド技術! OpenShift
試して学べるクラウド技術! OpenShift試して学べるクラウド技術! OpenShift
試して学べるクラウド技術! OpenShiftEtsuji Nakai
 
SORACOM Technology Camp 2018 | A3. IoT×クラウドデザインパターン
SORACOM Technology Camp 2018 | A3. IoT×クラウドデザインパターンSORACOM Technology Camp 2018 | A3. IoT×クラウドデザインパターン
SORACOM Technology Camp 2018 | A3. IoT×クラウドデザインパターンSORACOM,INC
 
キャリア網の完全なソフトウェア制御化への取り組み (沖縄オープンデイズ 2017) / Telecommunication Infrastructure ...
キャリア網の完全なソフトウェア制御化への取り組み (沖縄オープンデイズ 2017) / Telecommunication Infrastructure ...キャリア網の完全なソフトウェア制御化への取り組み (沖縄オープンデイズ 2017) / Telecommunication Infrastructure ...
キャリア網の完全なソフトウェア制御化への取り組み (沖縄オープンデイズ 2017) / Telecommunication Infrastructure ...KenzoOkuda
 
[Intermediate 01] イントロダクション / Bitcoin を動作させる
[Intermediate 01] イントロダクション / Bitcoin を動作させる[Intermediate 01] イントロダクション / Bitcoin を動作させる
[Intermediate 01] イントロダクション / Bitcoin を動作させるYuto Takei
 
TypeScript製フレームワーク「Nest」のご紹介
TypeScript製フレームワーク「Nest」のご紹介TypeScript製フレームワーク「Nest」のご紹介
TypeScript製フレームワーク「Nest」のご紹介bitbank, Inc. Tokyo, Japan
 
SORACOM Conference Discovery 2017 | E3. デバイスからのクラウド連携パターン
SORACOM Conference Discovery 2017 | E3. デバイスからのクラウド連携パターンSORACOM Conference Discovery 2017 | E3. デバイスからのクラウド連携パターン
SORACOM Conference Discovery 2017 | E3. デバイスからのクラウド連携パターンSORACOM,INC
 
Blockchain EXE #16:Hyperledger fabricの技術動向とファイナンシャルエンジニアリング視点でのトークンエコノミー|平山 毅...
Blockchain EXE #16:Hyperledger fabricの技術動向とファイナンシャルエンジニアリング視点でのトークンエコノミー|平山 毅...Blockchain EXE #16:Hyperledger fabricの技術動向とファイナンシャルエンジニアリング視点でのトークンエコノミー|平山 毅...
Blockchain EXE #16:Hyperledger fabricの技術動向とファイナンシャルエンジニアリング視点でのトークンエコノミー|平山 毅...blockchainexe
 
【Connected.T5】SORACOMと繋がるクラウドサービス
【Connected.T5】SORACOMと繋がるクラウドサービス【Connected.T5】SORACOMと繋がるクラウドサービス
【Connected.T5】SORACOMと繋がるクラウドサービスSORACOM,INC
 

Similar to MagicOnion~C#でゲームサーバを開発しよう~ (20)

Magic Leap で WebRTC 触ってみた
Magic Leap で WebRTC 触ってみたMagic Leap で WebRTC 触ってみた
Magic Leap で WebRTC 触ってみた
 
Zynga
ZyngaZynga
Zynga
 
Aws privte20110406 arai
Aws privte20110406 araiAws privte20110406 arai
Aws privte20110406 arai
 
Dapr × Kubernetes ではじめるポータブルなマイクロサービス(CloudNative Days Tokyo 2020講演資料)
Dapr × Kubernetes ではじめるポータブルなマイクロサービス(CloudNative Days Tokyo 2020講演資料)Dapr × Kubernetes ではじめるポータブルなマイクロサービス(CloudNative Days Tokyo 2020講演資料)
Dapr × Kubernetes ではじめるポータブルなマイクロサービス(CloudNative Days Tokyo 2020講演資料)
 
Introduction to NetOpsCoding
Introduction to NetOpsCodingIntroduction to NetOpsCoding
Introduction to NetOpsCoding
 
【Unity道場京都スペシャル4】Unityによるリアルタイム通信とMagicOnionによるC#大統一理論の実現
【Unity道場京都スペシャル4】Unityによるリアルタイム通信とMagicOnionによるC#大統一理論の実現【Unity道場京都スペシャル4】Unityによるリアルタイム通信とMagicOnionによるC#大統一理論の実現
【Unity道場京都スペシャル4】Unityによるリアルタイム通信とMagicOnionによるC#大統一理論の実現
 
IoTと業務システムをつなぐgRPC/RESTサービスの開発と運用
IoTと業務システムをつなぐgRPC/RESTサービスの開発と運用IoTと業務システムをつなぐgRPC/RESTサービスの開発と運用
IoTと業務システムをつなぐgRPC/RESTサービスの開発と運用
 
Angularreflex20141210
Angularreflex20141210Angularreflex20141210
Angularreflex20141210
 
SORACOM Conference "Discovery" 2018 | F3. SORACOMで実現する “Intranet” Of Things バ...
SORACOM Conference "Discovery" 2018 | F3. SORACOMで実現する “Intranet” Of Things バ...SORACOM Conference "Discovery" 2018 | F3. SORACOMで実現する “Intranet” Of Things バ...
SORACOM Conference "Discovery" 2018 | F3. SORACOMで実現する “Intranet” Of Things バ...
 
TypeScriptへの入口
TypeScriptへの入口TypeScriptへの入口
TypeScriptへの入口
 
GPU Container as a Service を実現するための最新OSS徹底比較
GPU Container as a Service を実現するための最新OSS徹底比較GPU Container as a Service を実現するための最新OSS徹底比較
GPU Container as a Service を実現するための最新OSS徹底比較
 
Azure Antenna AI 概要
Azure Antenna AI 概要Azure Antenna AI 概要
Azure Antenna AI 概要
 
試して学べるクラウド技術! OpenShift
試して学べるクラウド技術! OpenShift試して学べるクラウド技術! OpenShift
試して学べるクラウド技術! OpenShift
 
SORACOM Technology Camp 2018 | A3. IoT×クラウドデザインパターン
SORACOM Technology Camp 2018 | A3. IoT×クラウドデザインパターンSORACOM Technology Camp 2018 | A3. IoT×クラウドデザインパターン
SORACOM Technology Camp 2018 | A3. IoT×クラウドデザインパターン
 
キャリア網の完全なソフトウェア制御化への取り組み (沖縄オープンデイズ 2017) / Telecommunication Infrastructure ...
キャリア網の完全なソフトウェア制御化への取り組み (沖縄オープンデイズ 2017) / Telecommunication Infrastructure ...キャリア網の完全なソフトウェア制御化への取り組み (沖縄オープンデイズ 2017) / Telecommunication Infrastructure ...
キャリア網の完全なソフトウェア制御化への取り組み (沖縄オープンデイズ 2017) / Telecommunication Infrastructure ...
 
[Intermediate 01] イントロダクション / Bitcoin を動作させる
[Intermediate 01] イントロダクション / Bitcoin を動作させる[Intermediate 01] イントロダクション / Bitcoin を動作させる
[Intermediate 01] イントロダクション / Bitcoin を動作させる
 
TypeScript製フレームワーク「Nest」のご紹介
TypeScript製フレームワーク「Nest」のご紹介TypeScript製フレームワーク「Nest」のご紹介
TypeScript製フレームワーク「Nest」のご紹介
 
SORACOM Conference Discovery 2017 | E3. デバイスからのクラウド連携パターン
SORACOM Conference Discovery 2017 | E3. デバイスからのクラウド連携パターンSORACOM Conference Discovery 2017 | E3. デバイスからのクラウド連携パターン
SORACOM Conference Discovery 2017 | E3. デバイスからのクラウド連携パターン
 
Blockchain EXE #16:Hyperledger fabricの技術動向とファイナンシャルエンジニアリング視点でのトークンエコノミー|平山 毅...
Blockchain EXE #16:Hyperledger fabricの技術動向とファイナンシャルエンジニアリング視点でのトークンエコノミー|平山 毅...Blockchain EXE #16:Hyperledger fabricの技術動向とファイナンシャルエンジニアリング視点でのトークンエコノミー|平山 毅...
Blockchain EXE #16:Hyperledger fabricの技術動向とファイナンシャルエンジニアリング視点でのトークンエコノミー|平山 毅...
 
【Connected.T5】SORACOMと繋がるクラウドサービス
【Connected.T5】SORACOMと繋がるクラウドサービス【Connected.T5】SORACOMと繋がるクラウドサービス
【Connected.T5】SORACOMと繋がるクラウドサービス
 

More from torisoup

Doozy UI 使おうぜ! #unity_lt
Doozy UI 使おうぜ! #unity_ltDoozy UI 使おうぜ! #unity_lt
Doozy UI 使おうぜ! #unity_lttorisoup
 
Unityで作ったゲームをDLカードで配布してみた話 #roppongiunity
Unityで作ったゲームをDLカードで配布してみた話 #roppongiunityUnityで作ったゲームをDLカードで配布してみた話 #roppongiunity
Unityで作ったゲームをDLカードで配布してみた話 #roppongiunitytorisoup
 
ARでVRアバターを表示するシステムを構築しよう
ARでVRアバターを表示するシステムを構築しようARでVRアバターを表示するシステムを構築しよう
ARでVRアバターを表示するシステムを構築しようtorisoup
 
インタフェース完全に理解した
インタフェース完全に理解したインタフェース完全に理解した
インタフェース完全に理解したtorisoup
 
【Unity】 Behavior TreeでAIを作る
 【Unity】 Behavior TreeでAIを作る 【Unity】 Behavior TreeでAIを作る
【Unity】 Behavior TreeでAIを作るtorisoup
 
ObserverパターンからはじめるUniRx
ObserverパターンからはじめるUniRx ObserverパターンからはじめるUniRx
ObserverパターンからはじめるUniRx torisoup
 
Unityでオニオンアーキテクチャ
UnityでオニオンアーキテクチャUnityでオニオンアーキテクチャ
Unityでオニオンアーキテクチャtorisoup
 
Photon Cloud ことはじめ
Photon Cloud ことはじめPhoton Cloud ことはじめ
Photon Cloud ことはじめtorisoup
 
アバター生放送支援アプリ「アバれぽ」
アバター生放送支援アプリ「アバれぽ」アバター生放送支援アプリ「アバれぽ」
アバター生放送支援アプリ「アバれぽ」torisoup
 
UnityとNCMBでユーザ管理を実装してみた話
UnityとNCMBでユーザ管理を実装してみた話UnityとNCMBでユーザ管理を実装してみた話
UnityとNCMBでユーザ管理を実装してみた話torisoup
 
Task vs Observable
Task vs ObservableTask vs Observable
Task vs Observabletorisoup
 
UniRxでPUNを使いやすくする
UniRxでPUNを使いやすくするUniRxでPUNを使いやすくする
UniRxでPUNを使いやすくするtorisoup
 
はじめてのUniRx
はじめてのUniRxはじめてのUniRx
はじめてのUniRxtorisoup
 
UniRxでMV(R)Pパターン をやってみた
UniRxでMV(R)PパターンをやってみたUniRxでMV(R)Pパターンをやってみた
UniRxでMV(R)Pパターン をやってみたtorisoup
 
未来のプログラミング技術をUnityで -UniRx-
未来のプログラミング技術をUnityで -UniRx-未来のプログラミング技術をUnityで -UniRx-
未来のプログラミング技術をUnityで -UniRx-torisoup
 
みくみくまうすについて&Unity で使えるコーディングノウハウ
みくみくまうすについて&Unity で使えるコーディングノウハウみくみくまうすについて&Unity で使えるコーディングノウハウ
みくみくまうすについて&Unity で使えるコーディングノウハウtorisoup
 
Unity講習会(初級)
Unity講習会(初級)Unity講習会(初級)
Unity講習会(初級)torisoup
 

More from torisoup (17)

Doozy UI 使おうぜ! #unity_lt
Doozy UI 使おうぜ! #unity_ltDoozy UI 使おうぜ! #unity_lt
Doozy UI 使おうぜ! #unity_lt
 
Unityで作ったゲームをDLカードで配布してみた話 #roppongiunity
Unityで作ったゲームをDLカードで配布してみた話 #roppongiunityUnityで作ったゲームをDLカードで配布してみた話 #roppongiunity
Unityで作ったゲームをDLカードで配布してみた話 #roppongiunity
 
ARでVRアバターを表示するシステムを構築しよう
ARでVRアバターを表示するシステムを構築しようARでVRアバターを表示するシステムを構築しよう
ARでVRアバターを表示するシステムを構築しよう
 
インタフェース完全に理解した
インタフェース完全に理解したインタフェース完全に理解した
インタフェース完全に理解した
 
【Unity】 Behavior TreeでAIを作る
 【Unity】 Behavior TreeでAIを作る 【Unity】 Behavior TreeでAIを作る
【Unity】 Behavior TreeでAIを作る
 
ObserverパターンからはじめるUniRx
ObserverパターンからはじめるUniRx ObserverパターンからはじめるUniRx
ObserverパターンからはじめるUniRx
 
Unityでオニオンアーキテクチャ
UnityでオニオンアーキテクチャUnityでオニオンアーキテクチャ
Unityでオニオンアーキテクチャ
 
Photon Cloud ことはじめ
Photon Cloud ことはじめPhoton Cloud ことはじめ
Photon Cloud ことはじめ
 
アバター生放送支援アプリ「アバれぽ」
アバター生放送支援アプリ「アバれぽ」アバター生放送支援アプリ「アバれぽ」
アバター生放送支援アプリ「アバれぽ」
 
UnityとNCMBでユーザ管理を実装してみた話
UnityとNCMBでユーザ管理を実装してみた話UnityとNCMBでユーザ管理を実装してみた話
UnityとNCMBでユーザ管理を実装してみた話
 
Task vs Observable
Task vs ObservableTask vs Observable
Task vs Observable
 
UniRxでPUNを使いやすくする
UniRxでPUNを使いやすくするUniRxでPUNを使いやすくする
UniRxでPUNを使いやすくする
 
はじめてのUniRx
はじめてのUniRxはじめてのUniRx
はじめてのUniRx
 
UniRxでMV(R)Pパターン をやってみた
UniRxでMV(R)PパターンをやってみたUniRxでMV(R)Pパターンをやってみた
UniRxでMV(R)Pパターン をやってみた
 
未来のプログラミング技術をUnityで -UniRx-
未来のプログラミング技術をUnityで -UniRx-未来のプログラミング技術をUnityで -UniRx-
未来のプログラミング技術をUnityで -UniRx-
 
みくみくまうすについて&Unity で使えるコーディングノウハウ
みくみくまうすについて&Unity で使えるコーディングノウハウみくみくまうすについて&Unity で使えるコーディングノウハウ
みくみくまうすについて&Unity で使えるコーディングノウハウ
 
Unity講習会(初級)
Unity講習会(初級)Unity講習会(初級)
Unity講習会(初級)
 

Recently uploaded

PHP-Conference-Odawara-2024-04-000000000
PHP-Conference-Odawara-2024-04-000000000PHP-Conference-Odawara-2024-04-000000000
PHP-Conference-Odawara-2024-04-000000000Shota Ito
 
Postman LT Fukuoka_Quick Prototype_By Daniel
Postman LT Fukuoka_Quick Prototype_By DanielPostman LT Fukuoka_Quick Prototype_By Daniel
Postman LT Fukuoka_Quick Prototype_By Danieldanielhu54
 
新人研修のまとめ 2024/04/12の勉強会で発表されたものです。
新人研修のまとめ       2024/04/12の勉強会で発表されたものです。新人研修のまとめ       2024/04/12の勉強会で発表されたものです。
新人研修のまとめ 2024/04/12の勉強会で発表されたものです。iPride Co., Ltd.
 
Amazon SES を勉強してみる その12024/04/12の勉強会で発表されたものです。
Amazon SES を勉強してみる その12024/04/12の勉強会で発表されたものです。Amazon SES を勉強してみる その12024/04/12の勉強会で発表されたものです。
Amazon SES を勉強してみる その12024/04/12の勉強会で発表されたものです。iPride Co., Ltd.
 
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略Ryo Sasaki
 
IoT in the era of generative AI, Thanks IoT ALGYAN.pptx
IoT in the era of generative AI, Thanks IoT ALGYAN.pptxIoT in the era of generative AI, Thanks IoT ALGYAN.pptx
IoT in the era of generative AI, Thanks IoT ALGYAN.pptxAtomu Hidaka
 
UPWARD_share_company_information_20240415.pdf
UPWARD_share_company_information_20240415.pdfUPWARD_share_company_information_20240415.pdf
UPWARD_share_company_information_20240415.pdffurutsuka
 
20240412_HCCJP での Windows Server 2025 Active Directory
20240412_HCCJP での Windows Server 2025 Active Directory20240412_HCCJP での Windows Server 2025 Active Directory
20240412_HCCJP での Windows Server 2025 Active Directoryosamut
 
スマートフォンを用いた新生児あやし動作の教示システム
スマートフォンを用いた新生児あやし動作の教示システムスマートフォンを用いた新生児あやし動作の教示システム
スマートフォンを用いた新生児あやし動作の教示システムsugiuralab
 

Recently uploaded (9)

PHP-Conference-Odawara-2024-04-000000000
PHP-Conference-Odawara-2024-04-000000000PHP-Conference-Odawara-2024-04-000000000
PHP-Conference-Odawara-2024-04-000000000
 
Postman LT Fukuoka_Quick Prototype_By Daniel
Postman LT Fukuoka_Quick Prototype_By DanielPostman LT Fukuoka_Quick Prototype_By Daniel
Postman LT Fukuoka_Quick Prototype_By Daniel
 
新人研修のまとめ 2024/04/12の勉強会で発表されたものです。
新人研修のまとめ       2024/04/12の勉強会で発表されたものです。新人研修のまとめ       2024/04/12の勉強会で発表されたものです。
新人研修のまとめ 2024/04/12の勉強会で発表されたものです。
 
Amazon SES を勉強してみる その12024/04/12の勉強会で発表されたものです。
Amazon SES を勉強してみる その12024/04/12の勉強会で発表されたものです。Amazon SES を勉強してみる その12024/04/12の勉強会で発表されたものです。
Amazon SES を勉強してみる その12024/04/12の勉強会で発表されたものです。
 
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略
 
IoT in the era of generative AI, Thanks IoT ALGYAN.pptx
IoT in the era of generative AI, Thanks IoT ALGYAN.pptxIoT in the era of generative AI, Thanks IoT ALGYAN.pptx
IoT in the era of generative AI, Thanks IoT ALGYAN.pptx
 
UPWARD_share_company_information_20240415.pdf
UPWARD_share_company_information_20240415.pdfUPWARD_share_company_information_20240415.pdf
UPWARD_share_company_information_20240415.pdf
 
20240412_HCCJP での Windows Server 2025 Active Directory
20240412_HCCJP での Windows Server 2025 Active Directory20240412_HCCJP での Windows Server 2025 Active Directory
20240412_HCCJP での Windows Server 2025 Active Directory
 
スマートフォンを用いた新生児あやし動作の教示システム
スマートフォンを用いた新生児あやし動作の教示システムスマートフォンを用いた新生児あやし動作の教示システム
スマートフォンを用いた新生児あやし動作の教示システム
 

MagicOnion~C#でゲームサーバを開発しよう~