概要
gRPCは4つのRPC方式を持っています。
RPC方式 | 説明 | 使い所 |
---|---|---|
Unary(Simple) RPC | シンプルな1 Request - 1 Response方式 | 一般的なマイクロサービスなど |
Server streaming RPC | 1 Request - N Response方式 | サーバサイドプッシュ・フィードなど |
Client streaming RPC | N Request - 1 Response方式 | データアップロードなど |
Bidirectional streaming RPC | 1つのTPCコネクションの中で、RequestとResponseの送受信を任意数繰り返す。 WebSocketに近い? |
チャットなど双方向の同期が欲しい時。 コネクション数を節約したい時 |
ref: grpc / gRPC Concepts
それぞれ実装が異なるので、各方式での書き方を簡単に紹介します。
今回はSimple RPCのやり方です。
環境
- golang 1.9.2
- grpc 1.7.2
- protobuf 3.4.0
成果物
最終的に出来たコードはこちら
実装
名前を送ると挨拶してくれるサービスを用意します。
proto
syntax = "proto3"; package helloworld; service Greeter { rpc SayHello (HelloRequest) returns (HelloReply) {} } message HelloRequest { string name = 1; } message HelloReply { string message = 1; }
protoeasyでprotobufのコンパイルを簡単にする - Carpe Diemでも紹介しましたがコンパイルはprotoeasyで簡単に。
$ protoeasy --go --grpc .
サーバ
protoのコンパイルで生成されたコードに以下のインタフェースが用意されているので、
type GreeterServer interface { SayHello(context.Context, *HelloRequest) (*HelloReply, error) }
これを実装します。
package main import ( "log" "net" pb "github.com/jun06t/grpc-sample/unary/proto" "golang.org/x/net/context" "google.golang.org/grpc" ) const ( port = ":8080" ) type server struct{} func (s *server) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloReply, error) { return &pb.HelloReply{Message: "Hello " + in.Name}, nil } func main() { lis, err := net.Listen("tcp", port) if err != nil { log.Fatal(err) } s := grpc.NewServer() pb.RegisterGreeterServer(s, new(server)) err = s.Serve(lis) if err != nil { log.Fatal(err) } }
クライアント
alice
という名前を送ります。
package main import ( "log" pb "github.com/jun06t/grpc-sample/unary/proto" "golang.org/x/net/context" "google.golang.org/grpc" ) const ( address = "localhost:8080" ) func main() { conn, err := grpc.Dial(address, grpc.WithInsecure()) if err != nil { log.Fatal(err) } defer conn.Close() c := pb.NewGreeterClient(conn) req := &pb.HelloRequest{ Name: "alice", } resp, err := c.SayHello(context.Background(), req) if err != nil { log.Fatal(err) } log.Println("Reply: ", resp.Message) }
動作検証
$ go run client/main.go 2017/11/13 13:32:59 Reply: Hello alice
Hello alice
という返事が返ってきました。