PythonでgRPCを試してみる
今回はPythonでgRPCを試してみたので備忘録をまとめておこうと思います!!
ちょっとgRPCを使うことになったのですが、少し理解できなかったところもあったので試しに動かしてみた感じです。
■gRPCとは?
gRPCはクライアントアプリケーション内のローカルオブジェクトであるかのように、
別マシンに存在するサーバーアプリケーションのメソッドを直接呼び出すことが出来る仕組みになります。
gRPCを用いることで分散アプリケーションやサービスを容易に作成することが可能になります。
サーバー側ではインターフェースを実装し、gRPCサーバーを実行してクライアントの呼び出しに対して処理を行います。
クライアント側ではサーバーと同じメソッドを提供するスタブがあります。
gRPCではサーバー、クラアイント側にて様々な環境で実行及び通信が行えます。
例えば、C++言語でサーバーを作成しクライアント側でJavaやPythonを作成して通信することが可能になります。
■PythonでgRPCを使うための環境構築
ではまずは環境構築を行っていきます。
gRPCを使用するにあたり下記コマンドを実行します。
pip3 install grpcio or python3 -m pip install grpcio
次に、
pip3 install grpcio-tools or python3 -m pip install grpcio-tools
でgrpcio-toolsをインストールします。
grpcio-toolsは.protoファイルを扱うのに用います。
■gRPCサービス定義していく
ではまず、双方向通信を行うためのサービスの作成を行います。
helloworld.protoの名前でこちらのコードを作成します。
syntax = "proto3"; package sample; message HelloMessage{ string name = 1; string msg = 2; } message ReplyMessage{ string reply_msg = 1; } service SampleService{ rpc SayHello (HelloRequest) returns (HelloReply) {} }
こちらですが、
message HelloMessage{ string name = 1; string msg = 2; }
や
message ReplyMessage{ string reply_msg = 1; }
がサーバーとクライアント間で通信するためのメッセージ用のメソッドになります。
本コードにより、sayHelloメソッドでクライアントからHelloRequestを受け取り、サーバーからHelloReplyを返すサービスが生成されます。
ではこちらのコードからprotocol bufferに変換するために下記を実行します。
python3 -m grpc_tools.protoc -I. --python_out=. --grpc_python_out=. ./helloworld.proto
本コードを実行することにより、
・helloworld_pb2.py
・helloworld_pb2_grpc.py
が生成されるかと思います。
■サーバーサイド実装
ではサーバーサイド側を実装していきます。
import grpc import helloworld_pb2 import helloworld_pb2_grpc class Greeter(helloworld_pb2_grpc.GreeterServicer): def SayHello(self, request, context): return helloworld_pb2.HelloReply(message='Hello, %s!' % request.name) def serve(): server = grpc.server(futures.ThreadPoolExecutor(max_workers=10)) helloworld_pb2_grpc.add_GreeterServicer_to_server(Greeter(), server) server.add_insecure_port('[::]:50051') server.start() server.wait_for_termination() if __name__ == '__main__': serve()
まず、
class Greeter(helloworld_pb2_grpc.GreeterServicer): def SayHello(self, request, context): return helloworld_pb2.HelloReply(message='Hello, %s!' % request.name)
でクライアントから受け取るメソッドを実装します。
その後、
def serve(): server = grpc.server(futures.ThreadPoolExecutor(max_workers=10)) helloworld_pb2_grpc.add_GreeterServicer_to_server(Greeter(), server)
でメソッドを登録し、
server.add_insecure_port('[::]:50051')
server.start()
server.wait_for_termination()
で50051ポートでサーバーを起動しクライアントからのリクエストを待ちます。
■クライアントサイド実装
次にクライアントサイドを実装していきます。
コードはこちら。
import grpc import helloworld_pb2 import helloworld_pb2_grpc def run(): with grpc.insecure_channel('localhost:50051') as channel: stub = helloworld_pb2_grpc.GreeterStub(channel) response = stub.SayHello(helloworld_pb2.HelloRequest(name='you')) print("Greeter client received: " + response.message) if __name__ == '__main__': run()
サーバー側と結構似ていますね。
with grpc.insecure_channel('localhost:50051') as channel:
にて通信を確立し、
stub = helloworld_pb2_grpc.GreeterStub(channel)
でスタブを作成し、生成したスタブからサーバー側へリクエストとしてSayHelloメソッドを送信します。
response = stub.SayHello(helloworld_pb2.HelloRequest(name='you'))
■実際に動かしてみる
では、実際に動かしてみます。
サーバー側を、
python3 サーバーファイル名.py
と実行した後に、
クライアント側を、
python3 クライアントファイル名.py
と実行するとクライアント側で
Greeter client received: Hello, you!
と出力されるかと思います。
■最後に
今回はPythonでgRPCの基礎に関してまとめてみました。
gRPCは大きなシステムになった時にモジュール間で接続するのに役立ちそうだな。
ちょっと使っていこうかな!!
後、このブログを書いてる途中で普段使いのラズパイ3が故障した。。。
これから修理に入ります泣。