Download free for 30 days
Sign in
Upload
Language (EN)
Support
Business
Mobile
Social Media
Marketing
Technology
Art & Photos
Career
Design
Education
Presentations & Public Speaking
Government & Nonprofit
Healthcare
Internet
Law
Leadership & Management
Automotive
Engineering
Software
Recruiting & HR
Retail
Sales
Services
Science
Small Business & Entrepreneurship
Food
Environment
Economy & Finance
Data & Analytics
Investor Relations
Sports
Spiritual
News & Politics
Travel
Self Improvement
Real Estate
Entertainment & Humor
Health & Medicine
Devices & Hardware
Lifestyle
Change Language
Language
English
Español
Português
Français
Deutsche
Cancel
Save
Submit search
EN
Uploaded by
torisoup
PDF, PPTX
30,387 views
MagicOnion~C#でゲームサーバを開発しよう~
https://vsuc.connpass.com/event/146588/
Technology
◦
Read more
11
Save
Share
Embed
Embed presentation
Download
Download as PDF, PPTX
1
/ 176
2
/ 176
3
/ 176
4
/ 176
5
/ 176
6
/ 176
7
/ 176
8
/ 176
9
/ 176
10
/ 176
11
/ 176
12
/ 176
13
/ 176
14
/ 176
15
/ 176
16
/ 176
17
/ 176
18
/ 176
19
/ 176
20
/ 176
21
/ 176
22
/ 176
23
/ 176
24
/ 176
25
/ 176
26
/ 176
27
/ 176
28
/ 176
29
/ 176
30
/ 176
31
/ 176
32
/ 176
33
/ 176
34
/ 176
35
/ 176
36
/ 176
37
/ 176
38
/ 176
39
/ 176
40
/ 176
41
/ 176
42
/ 176
43
/ 176
44
/ 176
45
/ 176
Most read
46
/ 176
47
/ 176
Most read
48
/ 176
49
/ 176
50
/ 176
51
/ 176
52
/ 176
53
/ 176
54
/ 176
55
/ 176
56
/ 176
57
/ 176
58
/ 176
59
/ 176
60
/ 176
61
/ 176
62
/ 176
63
/ 176
64
/ 176
65
/ 176
66
/ 176
67
/ 176
68
/ 176
69
/ 176
70
/ 176
71
/ 176
72
/ 176
73
/ 176
74
/ 176
75
/ 176
76
/ 176
77
/ 176
78
/ 176
79
/ 176
80
/ 176
81
/ 176
82
/ 176
83
/ 176
84
/ 176
85
/ 176
86
/ 176
87
/ 176
88
/ 176
89
/ 176
90
/ 176
91
/ 176
92
/ 176
93
/ 176
94
/ 176
95
/ 176
96
/ 176
97
/ 176
98
/ 176
99
/ 176
100
/ 176
101
/ 176
102
/ 176
103
/ 176
104
/ 176
105
/ 176
106
/ 176
107
/ 176
108
/ 176
109
/ 176
110
/ 176
111
/ 176
112
/ 176
113
/ 176
114
/ 176
115
/ 176
116
/ 176
117
/ 176
118
/ 176
119
/ 176
120
/ 176
121
/ 176
122
/ 176
123
/ 176
124
/ 176
125
/ 176
126
/ 176
127
/ 176
128
/ 176
129
/ 176
130
/ 176
131
/ 176
132
/ 176
133
/ 176
134
/ 176
135
/ 176
136
/ 176
Most read
137
/ 176
138
/ 176
139
/ 176
140
/ 176
141
/ 176
142
/ 176
143
/ 176
144
/ 176
145
/ 176
146
/ 176
147
/ 176
148
/ 176
149
/ 176
150
/ 176
151
/ 176
152
/ 176
153
/ 176
154
/ 176
155
/ 176
156
/ 176
157
/ 176
158
/ 176
159
/ 176
160
/ 176
161
/ 176
162
/ 176
163
/ 176
164
/ 176
165
/ 176
166
/ 176
167
/ 176
168
/ 176
169
/ 176
170
/ 176
171
/ 176
172
/ 176
173
/ 176
174
/ 176
175
/ 176
176
/ 176
More Related Content
PDF
[CEDEC 2021] 運用中タイトルでも怖くない! 『メルクストーリア』におけるハイパフォーマンス・ローコストなリアルタイム通信技術の導入事例
by
Naoya Kishimoto
PDF
ピクサー USD 入門 新たなコンテンツパイプラインを構築する
by
Takahito Tejima
PDF
ネットワーク ゲームにおけるTCPとUDPの使い分け
by
モノビット エンジン
PDF
オンラインゲームの仕組みと工夫
by
Yuta Imai
PDF
ネットワーク ゲームにおけるTCPとUDPの使い分け
by
モノビット エンジン
PDF
Unity開発で使える設計の話+Zenjectの紹介
by
torisoup
PPTX
スマホゲームのチート手法とその対策 [DeNA TechCon 2019]
by
DeNA
PDF
【CEDEC2017】Unityを使ったNintendo Switch™向けのタイトル開発・移植テクニック!!
by
Unity Technologies Japan K.K.
[CEDEC 2021] 運用中タイトルでも怖くない! 『メルクストーリア』におけるハイパフォーマンス・ローコストなリアルタイム通信技術の導入事例
by
Naoya Kishimoto
ピクサー USD 入門 新たなコンテンツパイプラインを構築する
by
Takahito Tejima
ネットワーク ゲームにおけるTCPとUDPの使い分け
by
モノビット エンジン
オンラインゲームの仕組みと工夫
by
Yuta Imai
ネットワーク ゲームにおけるTCPとUDPの使い分け
by
モノビット エンジン
Unity開発で使える設計の話+Zenjectの紹介
by
torisoup
スマホゲームのチート手法とその対策 [DeNA TechCon 2019]
by
DeNA
【CEDEC2017】Unityを使ったNintendo Switch™向けのタイトル開発・移植テクニック!!
by
Unity Technologies Japan K.K.
What's hot
PDF
MagicOnion入門
by
torisoup
PDF
The Usage and Patterns of MagicOnion
by
Yoshifumi Kawai
PDF
「黒騎士と白の魔王」gRPCによるHTTP/2 - API, Streamingの実践
by
Yoshifumi Kawai
PDF
【Unite Tokyo 2019】Unityだったら簡単!マルチプレイ用ゲームサーバ開発 ~実践編~
by
UnityTechnologiesJapan002
PDF
Unityネットワーク通信の基盤である「RPC」について、意外と知られていないボトルネックと、その対策法
by
モノビット エンジン
PDF
Unityによるリアルタイム通信とMagicOnionによるC#大統一理論の実現
by
Yoshifumi Kawai
PDF
ソーシャルゲームのためのデータベース設計
by
Yoshinori Matsunobu
PDF
インタフェース完全に理解した
by
torisoup
PDF
Twitterのsnowflakeについて
by
moai kids
PDF
Observableで非同期処理
by
torisoup
PDF
Building the Game Server both API and Realtime via c#
by
Yoshifumi Kawai
PDF
Unityでオンラインゲーム作った話
by
torisoup
PPTX
本当は恐ろしい分散システムの話
by
Kumazaki Hiroki
PDF
UniTask入門
by
torisoup
PDF
新入社員のための大規模ゲーム開発入門 サーバサイド編
by
infinite_loop
PPTX
Unityで使える C# 6.0~と .NET 4.6
by
信之 岩永
PDF
Docker と ECS と WebSocket で最強のマルチプレイ・ゲームサーバを構築
by
gree_tech
PDF
できる!並列・並行プログラミング
by
Preferred Networks
PDF
UniRx完全に理解した
by
torisoup
PDF
Dockerからcontainerdへの移行
by
Kohei Tokunaga
MagicOnion入門
by
torisoup
The Usage and Patterns of MagicOnion
by
Yoshifumi Kawai
「黒騎士と白の魔王」gRPCによるHTTP/2 - API, Streamingの実践
by
Yoshifumi Kawai
【Unite Tokyo 2019】Unityだったら簡単!マルチプレイ用ゲームサーバ開発 ~実践編~
by
UnityTechnologiesJapan002
Unityネットワーク通信の基盤である「RPC」について、意外と知られていないボトルネックと、その対策法
by
モノビット エンジン
Unityによるリアルタイム通信とMagicOnionによるC#大統一理論の実現
by
Yoshifumi Kawai
ソーシャルゲームのためのデータベース設計
by
Yoshinori Matsunobu
インタフェース完全に理解した
by
torisoup
Twitterのsnowflakeについて
by
moai kids
Observableで非同期処理
by
torisoup
Building the Game Server both API and Realtime via c#
by
Yoshifumi Kawai
Unityでオンラインゲーム作った話
by
torisoup
本当は恐ろしい分散システムの話
by
Kumazaki Hiroki
UniTask入門
by
torisoup
新入社員のための大規模ゲーム開発入門 サーバサイド編
by
infinite_loop
Unityで使える C# 6.0~と .NET 4.6
by
信之 岩永
Docker と ECS と WebSocket で最強のマルチプレイ・ゲームサーバを構築
by
gree_tech
できる!並列・並行プログラミング
by
Preferred Networks
UniRx完全に理解した
by
torisoup
Dockerからcontainerdへの移行
by
Kohei Tokunaga
Similar to MagicOnion~C#でゲームサーバを開発しよう~
PDF
Unity C#と.NET Core(MagicOnion) C# そしてKotlinによるハーモニー
by
Yoshifumi Kawai
PPTX
Using or not using magic onion
by
Goichi Shinohara
PDF
【Unity道場京都スペシャル4】Unityによるリアルタイム通信とMagicOnionによるC#大統一理論の実現
by
UnityTechnologiesJapan002
PDF
NextGen Server/Client Architecture - gRPC + Unity + C#
by
Yoshifumi Kawai
PPTX
Azure PlayFab トレーニング資料
by
Daisuke Masubuchi
PDF
Implements OpenTelemetry Collector in DotNet
by
Yoshifumi Kawai
Unity C#と.NET Core(MagicOnion) C# そしてKotlinによるハーモニー
by
Yoshifumi Kawai
Using or not using magic onion
by
Goichi Shinohara
【Unity道場京都スペシャル4】Unityによるリアルタイム通信とMagicOnionによるC#大統一理論の実現
by
UnityTechnologiesJapan002
NextGen Server/Client Architecture - gRPC + Unity + C#
by
Yoshifumi Kawai
Azure PlayFab トレーニング資料
by
Daisuke Masubuchi
Implements OpenTelemetry Collector in DotNet
by
Yoshifumi Kawai
More from torisoup
PDF
Doozy UI 使おうぜ! #unity_lt
by
torisoup
PDF
Unityで作ったゲームをDLカードで配布してみた話 #roppongiunity
by
torisoup
PDF
ARでVRアバターを表示するシステムを構築しよう
by
torisoup
PDF
【Unity】 Behavior TreeでAIを作る
by
torisoup
PDF
ObserverパターンからはじめるUniRx
by
torisoup
PDF
Unityでオニオンアーキテクチャ
by
torisoup
PDF
Photon Cloud ことはじめ
by
torisoup
PDF
アバター生放送支援アプリ「アバれぽ」
by
torisoup
PDF
コールバックと戦う話
by
torisoup
PDF
UnityとNCMBでユーザ管理を実装してみた話
by
torisoup
PDF
Task vs Observable
by
torisoup
PDF
UniRxでPUNを使いやすくする
by
torisoup
PPTX
はじめてのUniRx
by
torisoup
PPTX
UniRxでMV(R)Pパターンをやってみた
by
torisoup
PPTX
未来のプログラミング技術をUnityで -UniRx-
by
torisoup
PPTX
みくみくまうすについて&Unity で使えるコーディングノウハウ
by
torisoup
PDF
Unity講習会(初級)
by
torisoup
Doozy UI 使おうぜ! #unity_lt
by
torisoup
Unityで作ったゲームをDLカードで配布してみた話 #roppongiunity
by
torisoup
ARでVRアバターを表示するシステムを構築しよう
by
torisoup
【Unity】 Behavior TreeでAIを作る
by
torisoup
ObserverパターンからはじめるUniRx
by
torisoup
Unityでオニオンアーキテクチャ
by
torisoup
Photon Cloud ことはじめ
by
torisoup
アバター生放送支援アプリ「アバれぽ」
by
torisoup
コールバックと戦う話
by
torisoup
UnityとNCMBでユーザ管理を実装してみた話
by
torisoup
Task vs Observable
by
torisoup
UniRxでPUNを使いやすくする
by
torisoup
はじめてのUniRx
by
torisoup
UniRxでMV(R)Pパターンをやってみた
by
torisoup
未来のプログラミング技術をUnityで -UniRx-
by
torisoup
みくみくまうすについて&Unity で使えるコーディングノウハウ
by
torisoup
Unity講習会(初級)
by
torisoup
Recently uploaded
PDF
基礎から学ぶ PostgreSQL の性能監視 (PostgreSQL Conference Japan 2025 発表資料)
by
NTT DATA Technology & Innovation
PDF
安価な ロジック・アナライザを アナライズ(?),Analyze report of some cheap logic analyzers
by
たけおか しょうぞう
PDF
第25回FA設備技術勉強会_自宅で勉強するROS・フィジカルAIアイテム.pdf
by
TomohiroKusu
PDF
visionOS TC「新しいマイホームで過ごすApple Vision Proとの新生活」
by
Sugiyama Yugo
PDF
PCCC25(設立25年記念PCクラスタシンポジウム):東京大学情報基盤センター テーマ1/2/3「Society5.0の実現を目指す『計算・データ・学習...
by
PC Cluster Consortium
PPTX
DrupalCon Nara 2025の記録 .
by
iPride Co., Ltd.
基礎から学ぶ PostgreSQL の性能監視 (PostgreSQL Conference Japan 2025 発表資料)
by
NTT DATA Technology & Innovation
安価な ロジック・アナライザを アナライズ(?),Analyze report of some cheap logic analyzers
by
たけおか しょうぞう
第25回FA設備技術勉強会_自宅で勉強するROS・フィジカルAIアイテム.pdf
by
TomohiroKusu
visionOS TC「新しいマイホームで過ごすApple Vision Proとの新生活」
by
Sugiyama Yugo
PCCC25(設立25年記念PCクラスタシンポジウム):東京大学情報基盤センター テーマ1/2/3「Society5.0の実現を目指す『計算・データ・学習...
by
PC Cluster Consortium
DrupalCon Nara 2025の記録 .
by
iPride Co., Ltd.
MagicOnion~C#でゲームサーバを開発しよう~
1.
MagicOnion 〜C#でゲームサーバを開発しよう〜 .NET Conf in
Tokyo 2019 #dotnetconfunity 2019/10/27 とりすーぷ
2.
⾃⼰紹介 • 「とりすーぷ」 • @toRisouP •
株式会社バーチャルキャスト 開発 • xR開発 • 最近はサーバ開発 • Microsoft MVP for Developer Technologies 2018〜2020
3.
今回の話 • MagicOnionについて解説 • 何のためのフレームワークか •
どんな機能があるのか • 環境構築 • 実装例の紹介 • 実装時の注意点 • デプロイ
4.
MagicOnionって何?
5.
MagicOnion is 何 •
ネットワーク通信のためのフレームワーク • Unityでのゲーム開発を中⼼に使えるネットワーク通信フレームワーク • サーバサイド:.NET Core • クライアントサイド:Unity / .NET Core • 開発はCysharp社 • MITライセンス
6.
MagicOnionのバックエンド • C# +
.NET Core / Unity • 通信プロトコル: gRPC • データフォーマット: MessagePack for C# • 定義したC#ファイルがそのままDSLになる • C#インタフェースがAPIのエンドポイント • C#オブジェクトが通信データ構造(MessagePackObject)
7.
MagicOnionのバックエンド クライアント サーバ プロトコルはgRPC データフォーマットはMessagePack C#ファイルの定義がそのままAPIのエンドポイントに
8.
コード共有 • 定義したインタフェースやオブジェクトを、 サーバとクライアントで共有することで そのままAPI定義として利⽤できる
9.
コード共有 クライアント サーバ インタフェース定義 (APIエンドポイント) インタフェース定義されたC#ファイルを クライアント・サーバで共有
10.
例:APIエンド先⽃の定義 共有するインタフェースを定義
11.
実装 クライアント サーバ サーバ側はインタフェースを実装する 実装
12.
サーバ側実装
13.
呼び出し クライアント サーバ クライアント側はただ インタフェースのメソッドを呼び出すだけ メソッドコール (async/awiat)
14.
クライアント側の呼び出し gRPCのコネクションを貼ってからメソッドを呼ぶだけ インタフェースに定義されたメソッドをコール 裏で通信が⾏われ、結果はasync/awaitで待てる
15.
サーバ処理の呼び出しの流れ サーバ メソッド実⾏すると裏でサーバコードが呼び出されて その結果が返ってくるのをawaitで待てる
16.
共有ファイルを介した通信 クライアント サーバ 共有したインタフェースを介して クライアント/サーバ間の通信が可能になる
17.
MagicOnion 最⼤の特徴 • 通信レイヤを意識せずにサーバコードを呼び出せる •
サーバとクライアントでC#インタフェースを共有すればOK • 通信のデータ構造もC#で定義すればOK • async/awaitでメソッド呼び出しするだけでサーバの処理を実⾏できる • ただし、gRPCのコネクション管理だけは⾃前で管理しないとダメ(しょうがない)
18.
MagicOnionの機能紹介
19.
機能⼀覧 • 実装できるAPIの種類 • Service、StreamingHub •
Filter機能 • Filter • その他便利な機能 • Swagger、Telemetry
20.
APIの実装 • ⼤きく2つのAPI実装パターンがある • Service •
StreamingHub
21.
Service • Service • シンプルな単発のAPIを作成するのに使う •
1Request ‒ 1Response通信(中⾝はUnary RPC) • リクエストを投げた本⼈にのみレスポンスを返せる
22.
Service クライアント サーバRequest Response 1Requestに対して1Responseのみ返せるのが 「Service」で実装したAPI
23.
StreamingHub • StreamingHub • リアルタイム通信向け •
中⾝はBidirectional Streaming RPC • 仮想的なコネクションを貼ったままずっと維持する • クライアントとサーバが⾃由にメッセージを送受信できる • 全体へブロードキャストも可能
24.
StreamingHub クライアント サーバ Message クライアント同⼠がサーバを介して 相互通信できるのが「StremingHub」 Broadcast Broadcast
25.
機能⼀覧 • 実装できるAPIの種類 • Service、StreamingHub •
Filter機能 • Filter • その他便利な機能 • Swagger、Telemetry
26.
Filter • 通信の前後に処理を追加する機能 • サーバ側フィルタ •
Service、StreamingHubに適⽤可能 • クライアント側フィルタ • Serviceのみ対応
27.
Filterの実装例(サーバ側)
28.
Filterを反映する • Filterを付けたいクラス/メソッドにAttributeをつける • このメソッド/クラスのRPCが実⾏されるタイミングで、 定義したFilterを通過する
29.
Filterの⽤途 • 使⽤例 • 認証⽤のヘッダーを追加 •
メッセージの暗号化/復号化 • 通信ログ出⼒ • 通信をせずにダミーのレスポンスの差し替え • エラーメッセージのハンドリング • リトライ処理
30.
機能⼀覧 • 実装できるAPIの種類 • Service、StreamingHub •
Filter機能 • Filter • その他便利な機能 • Swagger、Telemetry
31.
便利な機能 • Swagger対応 • 「Service」で実装したメソッドをREST
APIとして実⾏できる • Webブラウザ上でAPIの動作確認ができる • デバッグに便利 • Telemetry対応 • MagicOnionの監視 • メトリクス
32.
今回の話 • MagicOnionについて解説 • 何のためのフレームワークか •
どんな機能があるのか • 環境構築 • 実装例の紹介 • 実装時の注意点 • デプロイ
33.
MagicOnionの環境構築
34.
環境構築 • MagicOnionは環境構築がちょっとたいへん • クライアント側(Unity)は⼿動でライブラリ追加が必要 •
コード共有 • コードジェネレート
35.
クライアント ライブラリ導⼊ • これらのライブラリを⼿動で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/
36.
Player Settingsも設定が必要 • Scripting
Define Symbols • ENABLE_UNSAFE_MSGPACK を書き⾜す • Allow ʻunsafeʼ Code • Enable
37.
ついでに導⼊するとよさげ • UniRx • Reactive
Extensions for Unity • イベント処理の整理に便利 • UniTask • ValueTask for Unity • Unity向けのAwaiter実装の提供 • ⾮同期周りにはコレ
38.
環境構築 • MagicOnionは環境構築がちょっとたいへん • クライアント側(Unity)は⼿動でライブラリ追加が必要 •
コード共有 • コードジェネレート
39.
コード共有について クライアント サーバ インタフェース定義 (APIエンドポイント) インタフェース定義されたC#ファイルを どうやってクライアント/サーバでコード共有するの?
40.
Unity側の制約 • C#コードはAssets/以下に配置しないといけない • UnityはAssets/以下のC#ファイルしかコンパイルしてくれない
41.
オススメの⽅法 • サーバ側のcsprojからUnity/Assets以下を参照する • 実体はUnity側にあり、それをサーバプロジェクトで開いているだけ 参照 Unityサーバプロジェクト
42.
プロジェクト構成の例 Assets/ Assets/Shared/ サーバプロジェクト(ソリューション構成) Server.Interfaces.csproj Server.Core.csproj プロジェクト構成の⼀例
43.
プロジェクト構成の例 Assets/ Assets/Shared/ サーバプロジェクト(ソリューション構成) Server.Interfaces.csproj Server.Core.csproj 共有⽤csprojからUnity/Assets/以下を参照する 参照 ファイルの実体はこっち
44.
プロジェクト構成の例 Assets/ Assets/Shared/ サーバプロジェクト(ソリューション構成) Server.Interfaces.csproj Server.Core.csproj ポイント:共有するcsprojと、サーバのコアロジックのcsprojを分離して コアプロジェクトから共有プロジェクトを参照する 参照
45.
プロジェクト構成の例 Assets/ Assets/Shared/ Server.Interfaces.csproj Server.Core.csproj git管理するときはこれらをまとめて1つのリポジトリに⼊れる これで1つの Git
Repository
46.
この⽅法のメリット • 設定が簡単 • csprojに数⾏書き⾜すだけで設定が終わる •
リポジトリをチェックアウトしてくればそのまま動く • 環境に依存しない • シンボリックリンクとかそういう⾯倒な作業もいらない • 相対パスさえ維持されていれば動く
47.
デメリット • リポジトリが1個にまとまってしまう • サーバのビルドにクライアントコードのcheckoutも必要になる •
クライアントの容量が⼤きくなってくるとCI/CDがツライことになる • 開発フローの整理が難しくなる • クライアント開発とサーバ開発が同じリポジトリで管理される • GitHubのissue/pr 欄が混ざる
48.
折半案 サーバ側 サーバプロジェクトのポジトリ Git Repository Git Repository ゲーム本体のリポジトリ
49.
折半案 サーバ側 ここのUnityプロジェクトは、 Headlessなクライアント + Debug
Scene が置かれる Git Repository Git Repository
50.
折半案 サーバ側 ゲーム本体のプロジェクトは 別のリポジトリとして運⽤する
51.
折半案 サーバ側 接続部分をunitypackageにまとめて 本体側でインポートする unitypackage
52.
補⾜:UnityPackageはどう管理する? • Unity Package
Managerで管理できる • Unity標準のパッケージマネージャ機能 • まだ発展途上 • ⾃前でレジストリを⽴てればオレオレライブラリも管理可能 • 余⼒があるならコレで管理すると良さそう
53.
環境構築 • MagicOnionは環境構築がちょっとたいへん • クライアント側(Unity)は⼿動でライブラリ追加が必要 •
コード共有 • コードジェネレート
54.
コードジェネレートの話 • MagicOnionの動作にはコードジェネレートが2回必要 • MagicOnionのインタフェース定義 •
MessagePackのオブジェクト定義 • ただし、ジェネレートが必要なのはUnity側のみ(サーバ側は不要) • ジェネレートしたコードはUnityプロジェクトに配置する
55.
ジェネレータの⽤意 • それぞれGitHubからダウンロードできる MagicOnion MessagePack
56.
ジェネレータの使い⽅ • 対象のcsprojをコマンドラインで指定して実⾏ • MagicOnnion/MessagePack共に同じコマンド引数で動く
57.
指定するcsproj • 共有するインタフェースとオブジェクトが含まれたもの • 共有するファイルだけまとめたcsprojを⽤意しておくと楽
58.
指定するcsprojの例 Assets/ Assets/Shared/ サーバプロジェクト(ソリューション構成) Server.Interfaces.csproj Server.Core.csproj これ!
59.
注意点 • ジェネレート対象のcsprojがMagicOnionとMessagePack に依存するようにしておくこと • 依存させておかないとコードジェネレートが動かない Server.Interfaces.csproj
60.
コマンド例 ./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/以下に⽣成
61.
MessagePackのResolver設定だけ忘れずに • Unityプロジェクトに次のようなコードを配置 • RuntimeInitializeOnLoadMethodで起動時に実⾏されるようにしておく
62.
Editor拡張でジェネレートできると楽 • MagicOnionのサンプルコードに実装例がある • https://github.com/Cysharp/MagicOnion/blob/master /samples/ChatApp/ChatApp.Unity/Assets/Editor/MenuItems .cs
63.
環境構築 まとめ • 環境構築がちょっと⼤変 •
csprojを編集する必要がある • コードジェネレートの整備が⼿間 • 開発フローはよく考えよう • Unity側とサーバ側、2つのプロジェクト管理を同時にやる必要 • gitリポジトリをどうわけるか、どういうフローで開発をすすめるのか • CI/CDとの相性
64.
今回の話 • MagicOnionについて解説 • 何のためのフレームワークか •
どんな機能があるのか • 環境構築 • 実装例の紹介 • 実装時の注意点 • デプロイ
65.
実装例の紹介
66.
実装例 • それぞれの実装例を紹介 • Service •
StreamingHub
67.
Serviceの実装例 • サーバサイドで⾜し算する • シンプルに、引数に与えた数値を⾜して返す
68.
Serviceの実装例 • 実装⼿順 1. 共有するインタフェース/オブジェクトを定義 2.
サーバに実装を書く 3. サーバにコネクションする 4. Unity側で呼び出す
69.
Serviceの実装例 • 実装⼿順 1. 共有するインタフェース/オブジェクトを定義 2.
サーバに実装を書く 3. サーバにコネクションする 4. Unity側で呼び出す
70.
指定するcsprojの例 Assets/ Assets/Shared/ サーバプロジェクト(ソリューション構成) Server.Interfaces.csproj Server.Core.csproj ここに定義する (どっちに定義しても実体は1個なので同じ)
71.
Service:サーバサイドで計算する 1.サーバ/クライアントで共有するインタフェースを⽤意 IService<T>を継承したインタフェースを定義する インタフェース内に定義したメソッドがAPIエンドポイントになる
72.
Serviceの実装例 • 実装⼿順 1. 共有するインタフェース/オブジェクトを定義 2.
サーバに実装を書く 3. サーバにコネクションする 4. Unity側で呼び出す
73.
指定するcsprojの例 Assets/ Assets/Shared/ サーバプロジェクト(ソリューション構成) Server.Interfaces.csproj Server.Core.csproj ここに定義する
74.
例:サーバサイドで計算する 2.サーバ側で実装を⾏う インタフェースを実装 今回は引数を⾜して返すだけ
75.
Serviceの実装例 • 実装⼿順 1. 共有するインタフェース/オブジェクトを定義 2.
サーバに実装を書く 3. サーバにコネクションする 4. Unity側で呼び出す
76.
例:サーバサイドで計算する 3. サーバにコネクションする gRPCのチャンネルを作って
77.
例:サーバサイドで計算する 4. Unity側で呼び出す ICalculateServiceへのクライアントを作り
78.
例:サーバサイドで計算する 4. Unity側で呼び出す あとは普通にメソッドコールするだけ 通信の結果はasync/awaitで待つだけでOK
79.
例:サーバサイドで計算する サーバ メソッド実⾏すると裏でサーバコードが呼び出されて その結果が返ってくるのをawaitで待てる
80.
Serviceの実装は簡単 • リクエストに対して、処理を書いて、結果を返すだけ • かんたん •
クライアント側は普通にasync/awaitでメソッドを呼ぶだけ • サーバ側はインタフェースを実装するだけ
81.
StreamingHubの実装例
82.
StreamingHubはムズカシイ • StreamingHubはリアルタイム通信を実現する機構 • クライアントとサーバが相互にメソッドを呼び出し合える •
Serviceの実装と⽐べて複雑になりやすい • 「状態」がクライアントとサーバの両⽅で管理することになる • どのタイミングで何の処理が実⾏されるか、を整理しないとヤバイことになる
83.
StreamingHubの実装例 • サーバサイドでPlayerとその座標を管理する • Playerは移動量をサーバに送って、移動先を更新する •
Playerが移動したら全員に通知する • ⼊室時に既存のPlayer⼀覧を返す • Playerが⼊室/退室したら通知する • 単⼀のプロセスでのみ動く(プロセス間での協調は考えない)
84.
動作例 クライアントA サーバ クライアントがサーバにコネクションしている クライアントB
85.
動作例 クライアントA サーバ サーバ側で座標⼀覧を管理 クライアントB A: (1,
0 ,0 ) B: (0, 0, 2 )
86.
動作例 クライアントA サーバ MoveAsync()をクライアントがコールすると サーバ上の状態が書き換わり クライアントB A: (1
+1, 0 +0 ,0 +0 ) B: (0, 0, 2 ) MoveAsync( +1, +0, +0)
87.
動作例 クライアントA サーバ 新しい座標を全員に通知する クライアントB A: (1,
0 ,0 ) B: (0, 0, 2 ) OnPlayerMoved( id: A, position: (1,0,0) ) OnPlayerMoved( id: A, position: (1,0,0) )
88.
動作例 クライアントA サーバ 新しいクライアントが接続してきたら サーバ側で新しいPlayerIdを発⾏して返す クライアントB A: (1,
0 ,0 ) B: (0, 0, 2 ) C: (0, 0, 0) クライアントC Task<int> JoinAsync() => id: 12345
89.
動作例 クライアント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) )
90.
動作例 クライアント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)
91.
動作例
92.
実装順序 • 実装順序 1. インタフェース定義 2.
通信のオブジェクト定義 3. サーバ側実装 4. クライアント側実装
93.
例:座標管理 1. インタフェース定義 • 定義するインタフェースは2つある •
サーバ → クライアント(Receiver) • クライアント → サーバ(Hub)
94.
1.インタフェース定義(Receiver) • サーバ→クライアント(Receiver) • クライアントで実装するメソッド •
サーバから呼び出される
95.
1.インタフェース定義(Hub) • クライアント→サーバ(Hub) • サーバで実装するメソッド •
クライアントが呼び出す
96.
2.通信のオブジェクト定義 • 通信に利⽤するデータ構造を定義する • MessagePackObjectとして定義する •
(定義したあとはMessagePackのコードジェネレートが必要)
97.
2.通信⽤オブジェクトの定義 • 「プレイヤの状態」を扱うデータ構造
98.
2.通信⽤オブジェクトの定義 • 「プレイヤの状態」を扱うデータ構造 サーバサイドは「MessagePack.UnityShims」を導⼊すると Unityのデータ構造がそのまま使えて便利
99.
3.サーバ側の実装 • StreamingHubの特性を覚えよう • 1コネクションごとに新しいインスタンスが⽣成して割り当てられる •
コネクションが維持されている限り同じインスタンスが使われる (インメモリで状態が保持され続ける)
100.
StreamingHubの図 サーバプロセス StreamingHub StreamingHub StreamingHub クライアント Application Application Service 1コネクションごとにStreamingHubの インスタンスが⽣成されて、それが維持される Domain
101.
Application Domain Application Service StreamingHubの図 サーバプロセス StreamingHub StreamingHub StreamingHub クライアント Hub間でデータを共有するなら、 Hubより後ろ側の実装でイイカンジに処理するとヨサソウ
102.
今回の例 サーバプロセス PlayerHub PlayerHub PlayerHub クライアント PlayerManager 今回はレイヤ構造を作らずにシンプルな形でつくる (本当はクリーンアーキテクチャとかに則った⽅がいい) インメモリでPlayerの状態を 保持するオブジェクト
103.
3.サーバ側の実装 • PlayerManager • Playerの状態をインメモリで管理するシングルトンなオブジェクト •
各Hubのインスタンスが同時にアクセスするオブジェクトなので、 中⾝の実装はThread Safeにつくる必要がある
104.
3.サーバ側の実装 • PlayerHub 1/5 •
コンストラクタ
105.
3.サーバ側の実装 • PlayerHub 1/5 •
コンストラクタ インメモリで状態を保持できる
106.
3.サーバ側の実装 • PlayerHub 1/5 •
コンストラクタ PlayerManagerはDIで渡される
107.
3.サーバ側の実装 • PlayerHub 2/5 •
新規参加処理「JoinAsync()」
108.
3.サーバ側の実装 • PlayerHub 2/4 •
新規参加処理「JoinAsync()」 1. 新しいPlayerをPlayerManagerに作ってもらう 2. このHubをGroupに登録 3. 既存のクライアントにメッセージ発⾏ & My IDをreturn
109.
3.サーバ側の実装 • PlayerHub 2/4 •
新規参加処理「JoinAsync()」 1. 新しいPlayerをPlayerManagerに作ってもらう 2. このHubをGroupに登録 3. 既存のクライアントにメッセージ発⾏ & My IDをreturn
110.
3.サーバ側の実装 • PlayerHub 2/4 •
新規参加処理「JoinAsync()」 1. 新しいPlayerをPlayerManagerに作ってもらう 2. このHubをGroupに登録 3. 既存のクライアントにメッセージ発⾏ & My IDをreturn
111.
3.サーバ側の実装 • PlayerHub 2/4 •
新規参加処理「JoinAsync()」 1. 新しいPlayerをPlayerManagerに作ってもらう 2. このHubをGroupに登録 3. 既存のクライアントにメッセージ発⾏ & My IDをreturn めっちゃ⼤事!!!
112.
Group • Hub同⼠を束ねる機能 • マッチングに合わせてHubをグルーピングする機能 •
⽂字列を指定してGroupに参加できる • 同じGroup内にメッセージをまとめて発⾏(Broadcast)できる
113.
StreamingHubの「Group」 サーバプロセス PlayerHub PlayerHub PlayerHub クライアント メッセージのBroadcastは 同⼀GroupのHubにつないだクライアントに対して送ることができる Group “A” Group “A” Group
“B” 同じGroup内なら メッセージが送れる Groupはまたげない Broadcast()
114.
Broadcastの種類 • Broadcast(IGroup) • 指定Group内の、クライアント全員に送信 •
BroadcastToSelf(IGroup) / BroadcastExceptSelf(IGRoup) • ⾃分に対してのみ送信 / ⾃分以外の全員に送信 • BroadcastExcept(IGRoup, Guid / Guid[]) • 指定Group内の、指定のクライアントを除く全員に送信 • BroadcastTo(IGRoup, Guid / Guid[]) • 指定Group内の、指定のクライアントのみへ送信
115.
3.サーバ側の実装 • PlayerHub 2/5 •
新規参加処理「JoinAsync()」 今回はGroupは1つに固定 (参加したクライアントが全員同じ部屋にマッチングする)
116.
3.サーバ側の実装 • PlayerHub 3/5 •
既存のPlayer情報を取得して返す
117.
3.サーバ側の実装 • PlayerHub 4/5 •
移動処理 • 座標更新をしたあと、OnPlayerMovedメッセージをBroadcast
118.
3.サーバ側の実装 • PlayerHub 5/5 •
切断処理
119.
実装順序 • 実装順序 1. インタフェース定義 2.
通信のオブジェクト定義 3. サーバ側実装 4. クライアント側実装
120.
4.クライアント側 • HubClientの⽣成
121.
4.クライアント側 • 参加して既存Playerの状態復元
122.
4.クライアント側 • 移動処理 • ⼊⼒があったらサーバのMoveAsync()を呼ぶ
123.
4.クライアント側 • 移動コールバック • サーバからPlayerの座標更新通知がくる •
メッセージをもとに、そのIDのPlayerの座標を更新(描画)
124.
動作例
125.
StreamingHubの実装 • Serviceより実装が複雑になりやすい • どの状態を、誰が保持して、どこまで再現するのか?の管理が⼤変 •
StreamingHubのインスタンスがステートフルである • 後から接続したクライアントと既存のクライアントの同期をどこまで担保するか • クライアントとサーバの実装が密結合化する • データフロー、ロジックの流れを精査しないとグチャグチャになる • ドメインイベントを起因にしてメッセージを発⾏するスタイルがゴチャらなさそう
126.
「実装例の紹介」のまとめ • Serviceの実装は、かんたん • REST
APIのControllerを作るのと⼤差ない • Filterと合わせると便利 • StreamingHubは、表現⼒が⾼いがムズカシイ • なんでもできそうな代わりに、整えるのが難しい • バックエンド側のアーキテクチャをかなり考える必要あり
127.
今回の話 • MagicOnionについて解説 • 何のためのフレームワークか •
どんな機能があるのか • 環境構築 • 実装例の紹介 • 実装時の注意点 • デプロイ
128.
実装時の注意点
129.
覚えておくといいテクニックとか • クライアント側 • gRPCのコネクション管理ちゃんとやろう •
サーバ側 • Server GC使おう • ThreadPoolのサイズを増やそう • Generic Host使おう
130.
クライアント側 • gRPCのコネクション管理を気をつけよう
131.
gRPCのコネクション管理 • C#のgRPC Client(Channel)はUnmanaged •
Channelを利⽤している部分のDisposeを忘れるとすぐリークする • Dispose漏れがある状態でコネクションを閉じようとすると、やばい • Unity Editorごと巻き込んでフリーズしたり、アプリが正しく終了できなかったり MagicOnionの場合は、MagicOnion ClientのDisposeを必ず呼ぶこと
132.
管理する機構を作るとヨサソウ • マネージャをDisposeしたら関連するClientもまとめて Disposeする、みたいな機構を⽤意しておくとよさそう
133.
希望の光 • マネージドgRPCクライアント「grpc-dotnet」 • .NET
Core 3.0向け • Unityではまだ使えない • 今後に期待
134.
サーバ側 • Server GCを使おう •
ThreadPoolのサイズを増やそう • Generic Hostを使おう
135.
Server GC • C#のGCモードを「Server」に切り替えよう •
Background garbage collectionが有効になる • CPUリソースの消費量が増える代わりに、Stop-the-worldが短くなる
136.
設定⽅法 • csprojに下記を追加 • ServerGarbageCollection
= true
137.
覚えておくといいこと(サーバ) • Server GCを使おう •
ThreadPoolのサイズを増やそう • Generic Hostを使おう
138.
ThreadPoolのサイズ • C#のThreadPoolの拡張速度は遅い • スループットを上げるにはあらかじめ⼤きめにしておくと良い (最⼤1000まで、デフォルト値は25)
139.
覚えておくといいこと(サーバ) • Server GCを使おう •
ThreadPoolのサイズを増やそう • Generic Hostを使おう
140.
Generic Host • ASP.NETから汎⽤機能を分離した公式フレームワーク •
メッセージング • バックグラウンドサービスの起動 • 依存関係の注⼊(DI) • ロギング • 設定ファイル(config)の読み込み • サーバアプリケーションで必須な機能をまとめた便利パッケージ
141.
MagicOnion on GenericHost •
「MagicOnion.Hosting」パッケージを追加すればOK • あとは起動処理をGenericHost⾵にすればOK
143.
Configファイルの読み込み設定 ・./config/local.jsonの読み込み ・環境変数のバインド ・起動時のコマンドライン引数の読み込み
144.
DIの設定 ・PlayerManager をSingletonとしてBind
145.
ログの設定 ・コンソールにログを流す
146.
MagicOnionの起動設定
147.
例:Configの読み込み • Jsonファイルを配置して読み込み設定を書いておけば ./config/local.json
148.
DIでConfigオブジェクトが渡される
149.
Logging • ILogger<T>をDIして使う
150.
実装の注意点 まとめ • gPRCのコネクション管理はマジで気をつけよう •
切断時の処理とか再接続とか考えると頭痛いけどガンバッテ… • Generic Hostを使おう • コレいれておけば雑務な部分は全部やってくれる • 既存のASP.NETの資産がそのまま流⽤できて便利
151.
今回の話 • MagicOnionについて解説 • 何のためのフレームワークか •
どんな機能があるのか • 環境構築 • 実装例の紹介 • 実装時の注意点 • デプロイ
152.
MagicOnionのデプロイ
153.
デプロイ • どういう構成で、どこで、どうやって動かす? • どこでビルドするの •
どこでどう動かすの • MagicOnionのサーバ構成
154.
デプロイ • どういう構成で、どこで、どうやって動かす? • どこでビルドするの •
どこでどう動かすの • MagicOnionのサーバ構成
155.
どうするの • サーバで動かすならDockerビルドしよう • ビルドするならCircle
CIが便利 • Kubernetesでコンテナ管理がよさ • もちろんコレ以外のやり⽅でもできるけど、多分コレが⼀番無難な選択だと思う
156.
Kubernetes • Dockerコンテナのオーケストレーションツール • インフラ構成をyamlファイルで管理できる便利システム •
yamlにどのマシン(Node)に、何のコンテナをどう起動するか(Pod)を書いて applyすればそのとおりにコンテナが起動してくれる • 開発元はGoogle • 現状、Dockerのデファクトスタンダード • AWS、GCP、Azureももちろん対応している
157.
デプロイ • どういう構成で、どこで、どうやって動かす? • どこでビルドするの •
どこでどう動かすの • MagicOnionのサーバ構成
158.
MagicOnionのサーバ構成 • ⼤きく分けて2つの構成が選べる • ステートフル構成 •
ステートレス構成 • それぞれ⼀⻑⼀短ある
159.
ステートフル構成 • プロセス側で状態を保持する構成 • 簡単にいうと「インメモリでデータを保持する」実装 •
あるGroupに参加したいならそのGroupの状態を持っている インスタンスを選んで接続する必要がある
160.
ステートフル構成 MagicOnionインスタンス(サーバプロセス) StreamingHub クライアント 各インスタンスに対応するGroupが決まっている Group “A” StreamingHub StreamingHub StreamingHub StreamingHub Group “B” Group
“C” 状態(インメモリ) インスタンス X AとBを担当 インスタンス Y Cを担当
161.
ステートフル構成 MagicOnionインスタンス(サーバプロセス) StreamingHub クライアント 新しいクライアントがつなぐ場合は、 接続したいGroupに合わせてインスタンスを選択する必要がある StreamingHub StreamingHub StreamingHub StreamingHub 状態(インメモリ) インスタンス X AとBを担当 インスタンス Y Cを担当 新しい クライアント 「Bに⼊りたいから Xにつなぐ!」
162.
ステートフル構成 • メリット • リアルタイム通信に向く •
⼤量のメッセージのBroadcastがプロセス内で完結する • データの保持もインメモリで済む • 外部ストレージへのトランザクション処理が省略できる • インメモリで済む限りにおいて、外部ストレージを使わないので⾼速に処理可能
163.
ステートフル構成 • デメリット • オートスケールしにくい、LBが使えない、停⽌メンテが必要になるかも •
ステートフルなのでプロセスをいきなり落とすと死ぬ • LBの代わりに、サービスディスカバリの⽤意が必要 • Kubernetesと相性が悪い • External IP / Node Portの設定をがんばる必要がある • Agonesが使えたらマシになりそう
164.
サービスディスカバリ • 「ホスト」と「インスタンス」の割当を管理するシステム インスタンス X
インスタンス Y Service Discovery インスタンスが保持する Groupの情報を同期 10.0.0.5:12345 10.0.0.6:12345
165.
サービスディスカバリ • 「ホスト」と「インスタンス」の割当を管理するシステム インスタンス X
インスタンス Y Service Discovery 10.0.0.5:12345 10.0.0.6:12345 「 に繋ぎたい」 「10.0.0.5:12345につないでね」
166.
Agones • GoogleとUbisoftが共同で開発している マルチプレイヤーゲーム向けのサーバ管理システム • Kubernetesと協調して動く •
マッチングに合わせてコンテナの起動、接続、停⽌を管理してくれる • OSS • 2019年9⽉にv1.0.0が出たばかり • Ubisoftが使っていた実績はあるが、巷に知⾒があまりない • 興味がある⼈は⼿を出すとよさそう
167.
ステートレス構成 • プロセス上に状態を持たない構成 • MagicOnionのプロセス同⼠がバックエンドで協調して動く •
どのインスタンスにつないでも好きなGroupに参加できる
168.
ステートレス構成 MagicOnionクライアント クライアントはMagicOnionのホストがどうなっているかを 意識せずにすきなGroupに参加できる Group “A” Group “B” Group
“C” RedisGroup “B” Group “A” Group “A” Group “C” Load Balancer MagicOnionのメッセージは Redis pub/sub経由でBroadcast
169.
ステートレス構成にするには • バックエンドにRedisが必要 • Redis
Clusterをバックエンドに組む必要がある • MagicOnionに追加のパッケージが必要 • 「MagicOnion.Redis」を追加
170.
ステートレス構成 • メリット • オートスケーリングができる •
Load Balancerで負荷分散できる • ローリングアップデートしやすい • Kubernetesもニッコリ
171.
ステートレス構成 • デメリット • リアルタイム通信に向いてない •
メッセージのBroadcastにプロセスをまたぐ必要がある • データストレージへのトランザクション管理 • パフォーマンスがRedis依存 • MagicOnionがバックエンドにRedis pub/subを利⽤するため • Redis Clusterを組んでてもpub/subの性能はさほど向上しない • ⼤規模になるとここが⼀番ツライことになる
172.
構成についてのまとめ • リアルタイム通信なら「ステートフル」のほうがオススメ • ただしKubernetes周りが結構キビシイ •
Agonesなんとかしてくれー!!! • サービスディスカバリは⾃前で作るのがヨサソウ
173.
まとめ
174.
MagicOnionについてのまとめ • サーバサイドもC#で「いい感じ」にサーバが作れる • ゲーム向けのリアルタイム通信⽤途にも耐えうる •
クライアントとサーバをC#で統⼀できる • クライアントエンジニアをそのままサーバ開発に回せる • 最新のC#を使える!楽しい!
175.
ただし… • 開発フローの整備が課題 • クライアントとサーバがかなり密結合する •
プロジェクト全体でフローを決めないと混乱しそう • サーバサイドの開発知識はある程度必要 • クライアントエンジニアを即⽇でサーバ開発に回すのはキビシイ • ある程度のスイッチングコストは⾒越しておくべき
176.
総評 • 「MagicOnioは、いいぞ。」 • サーバサイドもC#で書けるのは、結構気持ちいい(個⼈の感想) •
クライアントとサーバの開発の境⽬がなくなる • MagicOnionというか、Kubernetesの運⽤の⽅がムズい • Agonesに期待
Download