MagicOnionとは
gRPCを用いた.NET/Unity間のリアルタイム通信ライブラリです
READMEでは、Windows上で動かすことを前提に書かれていたりしますが、
Linux/Macでも問題なく動作します。
(Install-Package
コマンドなどが記載されているので)
検証内容
今回はUnityは一切使用しません
MagicOnionとはどういうものかをREADMEに沿って検証するのみとなっています
検証環境
- Mac OS Mojave 10.14.2
- .NET Core 2.1.301
サンプルプログラムを動かす
READMEに沿って、サーバー/クライアントのコードを動かしてみます
準備
サーバー側/クライアント側の両方のConsoleプロジェクトを作成します
- サーバー側
$ mkdir Server
$ cd Server
$ dotnet new console
$ dotnet add package MagicOnion
- クライアント側
$ mkdir Client
$ cd Client
$ dotnet new console
$ dotnet add package MagicOnion
これで準備完了です
サーバー側実装
https://github.com/Cysharp/MagicOnion#quick-start
こちらに記載されている、サーバー側プログラムをそのままコピーします
(Program.csとMyFirstService.cs)
クライアント側実装
軽く動作検証するだけですので、ちょっとだけコードを変更し以下のようにします
また、クラアント側には MyFirstService
の実態は不要でインターフェースを定義したファイルだけあれば良いです
(後述しますが、これがIDLとなります)
class Program
{
static void Main(string[] args)
{
// standard gRPC channel
var channel = new Channel("localhost", 12345, ChannelCredentials.Insecure);
// get MagicOnion dynamic client proxy
var client = MagicOnionClient.Create<IMyFirstService>(channel);
// call method.
var result = client.SumAsync(100, 200).GetAwaiter().GetResult();
Console.WriteLine("Client Received:" + result);
}
}
手を加えた箇所は以下のところです
本来はasyncで非同期実行するところですが、GetAwaiter().GetResult()
と書くと同期的に処理が終わるまで待機してくれます
(メインスレッドが固まるのでリリース開発版などでの利用はおすすめしません...)
client.SumAsync(100, 200).GetAwaiter().GetResult();
動かしてみる
サーバープログラムの起動
まず、サーバー側プログラムを動かします。
単純な検証ですので dotnet run
コマンドで実行するだけです
$ cd Server
$ dotnet run
D0204 17:50:33.569109 Grpc.Core.Internal.UnmanagedLibrary Attempting to load native library "/Users/Hogehoge/.nuget/packages/grpc.core/1.17.0/lib/netstandard1.5/../../runtimes/osx/native/libgrpc_csharp_ext.x64.dylib"
D0204 17:50:33.672423 Grpc.Core.Internal.NativeExtension gRPC native library loaded successfully.
サーバーが待機状態で起動します
クライアントプログラムの起動
$ cd Client
$ dotnet run
Client Received:300
サーバーからのレスポンスを受けることが確認できます
また、サーバー側のログにも以下のように表示され、リクエストを処理できたことが確認できます
D0204 17:52:40.951573 Received:100, 200
特に苦労することもなくあっさり動いてくれました
ちょっと動かしただけでわかるメリット
サーバー/クライアント間でのIDLが不要!
通信仕様を共有するために、中間言語で書かれたIDLだったり、SwaggerなどでのAPI仕様を共有することが多いですが、MagicOnionでは、C#のインターフェースファイルをクライアントに渡すだけでサクッと通信ができます
デメリット
当たり前ですがすべてC#縛り...
その他1
コンパイル時に、
MyFirstService.cs(22,39): warning CS1998: この非同期メソッドには 'await' 演算子がないため、
同期的に実行されます。'await' 演算子を使用して非ブロッキング API 呼び出しを待機するか、
'await Task.Run(...)' を使用してバックグラウンドのスレッドに対して
CPU 主体の処理を実行することを検討してください。
という警告が出ますが、無視で。作者のサイトでも公式に言及されています
(Generalized async return types (Task-like)
は別途勉強しておかないと...)
http://neue.cc/2017/04/06_551.html
その他2
最近は、BlazorというWebのフロントエンドをC#で書けるものも出てきているので、
MagicOnionはUnity以外でも用途は色々とあるのではとちょっと思いました
https://blazor.net/