gRPC をインストール
まずは gRPC をインストールします。
gRPCと共に、RPCのシリアライゼーションを担う Protocol Buffers もインストールされるようです。
$ curl -fsSL https://goo.gl/getgrpc | bash -s python
もし、インストール中に以下のようなエラーが出た場合は homebrew が古いので brew update
を試してみてください。(Macの場合)
Error: undefined method `desc' for Grpc:Class
Please report this bug:
http://git.io/brew-troubleshooting
/usr/local/Library/Taps/grpc/homebrew-grpc/Formula/grpc.rb:2:in `<class:Grpc>'
・・・
.proto(IDL)を書く
Protocol Buffers のIDLを書きます。
以下の例ではサーボを動かすRPCを定義しています。
gRPC 自体は Protocol Buffers のプラグインとなっています。
(gRPC 以外にも RPC 実装はたくさんあります)
gateway.proto
syntax = "proto3";
package gateway;
message MoveServoRequest {
int32 servo_id = 1;
int32 position = 2;
}
message MoveServoResponse {
int32 current_position = 1;
}
service AVRGateway {
rpc MoveServo (MoveServoRequest) returns (MoveServoResponse) {}
}
IDLをコンパイルしてgRPCのpythonスクリプトを生成
以下の protoc
コマンドで、gateway_pb2.py
が生成されます。
$ protoc --python_out=. --grpc_out=. --plugin=protoc-gen-grpc=`which grpc_python_plugin` gateway.proto
gRPC用のサーバ/クライアントのコードを書く
上記のコマンドで生成されたPythonスクリプトをインポートすれば簡単にサーバ/クライアントが書けます。
gRPCのPythonライブラリ自体まだAlpha版なので、いろんなメソッドにearly_adopter_*というプレフィックスがついています。
gateway_server.py
import time
import gateway_pb2
class AVRGateway(gateway_pb2.EarlyAdopterAVRGatewayServicer):
def MoveServo(self, request, context):
print 'servo_id: %d, position: %d' % (request.servo_id, request.position)
return gateway_pb2.MoveServoResponse(current_position=150)
def serve():
server = gateway_pb2.early_adopter_create_AVRGateway_server(AVRGateway(), 9494, None, None)
server.start()
try:
while True:
time.sleep(100000)
except KeyboardInterrupt:
server.stop()
if __name__ == '__main__':
serve()
gateway_client.py
import gateway_pb2
def run():
with gateway_pb2.early_adopter_create_AVRGateway_stub('localhost', 9494) as stub:
response = stub.MoveServo(gateway_pb2.MoveServoRequest(servo_id=1, position=200), 10)
print "current position: " + str(response.current_position)
if __name__ == '__main__':
run()
実行
まずサーバを立ち上げます。
$ ls
gateway.proto gateway_client.py gateway_pb2.py gateway_server.py
$ python gateway_server.py
そして別のターミナルでクライアントを。
$ python gateway_client.py
current position: 150
D0729 10:42:14.835677000 140735135564544 iomgr.c:119] Waiting for 1 iomgr objects to be destroyed and executing final callbacks
サーバのほうでは
$ python gateway_server.py
servo_id: 1, position: 200
という感じで出力されていればOK。