gRPCってなんだって思って調べてたら実装してしまっていたので備忘録として残します。
ゴール
このようなディレクトリ構造でpythonクライアントとgoサーバー間でgRPCを実装していくことをゴールとします.
$GOPATH/src/pygo-grpc/
├ client/
| ├ app.py
| ├ hello_pb2_grpc.py (gRPC自動生成)
| └ hello_pb2.py (gRPC自動生成)
├ protos/
| └ hello.protc
└ server/
├ grpc-server/hello.pb.go (gRPC自動生成)
└ server.go
プロトコルを定義
-
$GOPATH
の配下に新しいワーキングディレクトリを作成し、プロトコルを定義します。
~ $ cd $GOPATH/src
src $ mkdir pygo-grpc;cd $_
pygo-grpc $ mkdir client protocs server server/grpc-server
pygo-grpc $ touch protocs/hello.proto
protocs/hello.proto
syntax = "proto3";
package hello;
service Hello {
rpc PushMsg (MsgStruct) returns (MsgStruct) {}
}
message MsgStruct {
string message = 1;
}
パラメータ、戻り値、呼び出しメソッドを定義しています。
今回は簡単なメッセージの通信を実装するので、PushMsg
というメソッドを定義し、そのパラメータと戻り値をどちらも同じMsgStruct
で定義します。
GoでgRPCサーバーを実装する
GoのgRPC周りのインストール
まだの人はチャチャッとやってしまいましょう。
go version // 1.6以上必要
go get -u google.golang.org/grpc // Install gRPC
go get -u github.com/golang/protobuf/protoc-gen-go // Install the protoc plugin
GoのgRPCコードを生成
protoファイルの場所とgRPCコードを生成する場所を指定。
pygo-grpc $ protoc -I protocs/ protocs/hello.proto --go_out=plugins=grpc:server/grpc-server/
server/grpc-server/hello.pb.go
が自動生成されます。
GoのgRPCサーバー実装
pygo-grpc $ touch server/server.go
server/server.go
package main
import (
"context"
"log"
"net"
"google.golang.org/grpc"
pb "pygo-grpc/server/grpc-server"
)
const (
port = ":50051"
)
type server struct {
pb.UnimplementedHelloServer
}
func (s *server) PushMsg(ctx context.Context, p *pb.MsgStruct) (*pb.MsgStruct, error) {
log.Printf("Received: %v", p.Message)
return &pb.MsgStruct{Message: "Hello " + p.Message}, nil
}
func main() {
lis, err := net.Listen("tcp", port)
if err != nil {
log.Fatalf("failed to listen: %v", err)
}
s := grpc.NewServer()
pb.RegisterHelloServer(s, &server{})
if err := s.Serve(lis); err != nil {
log.Fatalf("failed to serve: %v", err)
}
}
PythonでgRPCクライアントを実装する
pythonの仮想環境の立ち上げ
pygo-grpc $ virtualenv venv && source venv/bin/activate
venvはトレースしなくて大丈夫なので .gitignoreにでも
PythonのgRPC周りのインストール
(venv) pygo-grpc $ pip install grpcio
(venv) pygo-grpc $ pip install grpcio-tools
PythonのgRPCコードを生成
(venv) pygo-grpc $ python -m grpc_tools.protoc -I protocs --python_out=client --grpc_python_out=client protocs/hello.proto
client/hello_pb2_grpc.py
と client/hello_pb2.py
が自動生成されます
PythonのgRPCクラアイアント実装
client/app.py
from __future__ import print_function
import logging
import grpc
import hello_pb2
import hello_pb2_grpc
def run():
msg = input()
with grpc.insecure_channel('localhost:50051') as channel:
stub = hello_pb2_grpc.HelloStub(channel)
stub.PushMsg(hello_pb2.MsgStruct(message=msg))
if __name__ == '__main__':
logging.basicConfig()
run()
動作確認
まずサーバーを立ち上げ
pygo-grpc $ go run server/server.go
次にクライアントを立ち上げます
(venv) pygo-grpc $ python client/app.py
うまくいきました😆
参考
https://grpc.io/docs/quickstart/go/
https://grpc.io/docs/quickstart/python/