A certain engineer "COMPLEX"

.NETでRPCを試してみる gRPC編 第1回

Introduction


前回は導入手順の紹介しました。

C#をサポートしているので、試してみないわけにはいきません。
Pythonもサポートしており、簡単にテストできそうです。
内容としては、C#(クライアント)-Python(サーバー)とし、クライアントから送信した画像をサーバー側で反転して返すというプログラムになります。

今回のソースは下記になります。

Preparation


C#側は前回インストールしましたので省略します。

Python

Pythonにもインストールしておきます。
Pythonインタープリターは、いつも通りMinicondaになります。

pipでインストールする場合は、pipのバージョンが8以降であることが条件です。
バージョンは下記の手順で確認。

gRPCをインストールします。

続いて、gRPC toolsをインストールします。

gRPC toolsは proto というファイルから、サーバー、クライアント側のコードを生成するためのジェネレーターになります。

Source


gRPC tools

protoファイルを用意して、サーバー、クライアントのコードを生成します。

imageProc.proto

サンプルが github にありますが、面白くないので、手を加えます。

続いて、imageProc.protoからコードを生成します。
gRPC toolsから生成しますが、PythonとC#側でそれぞれ生成する必要があります。
また、言語用にそれぞれgRPC toolsがあるので、それぞれ入手します。

for Python

PythonでのgRPC toolsは下記のように使います。

今回のソース構成では、gRPC1フォルダにimageProc.protoがありますので、そこをカレントディレクトリにして下記を実行します。

これにより、Python\imageProc_pb2.pyPython\imageProc_pb2_grpc.py が生成されます。

for C#

C#側は少し面倒です。
まず、nugetを入手します。
これはVisual Studioから実行できるものではなく、スタンドアロンのコマンドラインツールです。

Available NuGet Distribution Versionsから、nuget.exe - recommended latest (v3.5.0)を選択します。
ダウンロードしたnuget.exeを適切な場所に展開し、ソースフォルダのpackagesフォルダをカレントディレクトにして、次のコマンドを入力します。

カレントディレクトリにGrpc.Tools.1.2.0が作成されます。
続いて、コードを生成します。
構文はPythonと似ています。

grpc_csharp_plugin.exeは先ほどのnuget.exeでGrpc.Toolsをインストールした際に、同時にインストールされます。
ですので、下記のようにしてimageProc.protoからコードを生成します。

これにより、gRPC\Contracts\ImageProc.csgRPC\Contracts\ImageProcGrpc.cs が生成されます。

Python

コードの生成が完了したので、Python側でgRPCを利用するコードを記述していきます。

imageProc_server.py

xxx_pb2_grpc.pyというファイルにて、クライアント、サービスの基底クラスが定義されていますので、これらから派生したクラスを実装していきます。
Python側がサーバーになるので、ImageProcServicerから派生します。

ImageProcは自動生成されたImageProcServicerから派生して適宜実装します。
今回は、入力されたバイナリデータを反転する処理を書いています。
main関数はserve関数を呼び出しています。
serve関数は、https://github.com/grpc/grpc/blob/master/examples/python/helloworld/greeter_server.pyを参考に記述しますので簡単です。

C#

MVVMで実装します。
画像ファイルを読み込むボタン、読み込んだ画像を表示するパネル、サーバーと通信するための送信ボタン、サーバーからの結果を表示するためのパネルを備えています。

また、実装を開始する前に、nugetでGoogle.Protobufをインストールします。

MainViewModel.cs

まずは、interfaceです。
Xaml上のButtonに対応するCommandと、Imgaeに対応するImageSourceを備えているだけです。

IMainViewModel.cs

IMainViewModelを継承しています。

OpenFileCommandは、画像ファイルをSystem.Windows.Media.Imaging.BitmapImageに変換して、SourceImageに設定するだけです。
注目は、ServerRequestCommandの下記の部分です。

ローカル(127.0.0.1)のポート50051に対して、gRPCで通信を確立し、APIを呼び出しています。
ImageProc.ImageProc.ImageProcClientは、gRPC toolsで自動生成しているものです。
通信に関係するコードはすべて自動で生成されるので、クライアント側は、ちょっとした呼び出しのコードを記述するだけで、簡単にサーバー側のAPIを呼び出せるわけです。

Test


サーバー側とクライアント側をテストしてみます。
サーバー側(imageProc_server.py)を起動し、任意の画像ファイルを読み込み、サーバー側APIを呼び出すと、反転した画像が返ってきます。

Conclusion


通信周りはすべて自動生成に任せ、ビジネスロジックの実装に注力できるのは、本当に楽です。
今時、ソケットだのコールバックだの考えるのは本当に面倒です。

Source Code

https://github.com/takuya-takeuchi/Demo/tree/master/gRPC1

コメントを残す

メールアドレスが公開されることはありません。

%d人のブロガーが「いいね」をつけました。