golangでgRPCを使う


gRPCはGoogleが作ったRPCのフレームワークで、Protocol bufferというシリアライズとプロトタイプをベースにしています。
http://www.grpc.io/

サンプル実装

クライアントがpingと書いたら、pongと返すだけのサーバです。
https://github.com/juntaki/grpc-sample

プロトタイプ

proto3というSyntaxでプロトタイプを作成する。プロトタイプにはざっくりと次のようなことを書きます。

書式 意味
message 構造体の形式
service 関数宣言
package パッケージ名

詳細は:https://developers.google.com/protocol-buffers/docs/proto3

protoファイルからのコード生成はこのREADMEのprotocコマンドに、--go_out=plugins=grpc:.をつけないとserviceが定義されません。
https://github.com/golang/protobuf

protoc --go_out=plugins=grpc:. *.proto

サーバ側の実装

streamingはmessageで定義した構造の配列を送れるイメージです。
双方向はClient側にもRecvで待っておいてもらえる実装というだけで送れる情報は普通のstreamingと変わりません。

  • SimpleRPC
  • Server-side streaming RPC
  • Client-side streaming RPC
  • Bidirectional streaming RPC

クライアント側の実装

サーバ側のRPCの種類に合わせて実装方法はいろいろですが、基本的にはgrpc.Dialで接続したあと、
NewXXXClientの戻り値の構造体からプロトタイプで実装したインタフェースを利用するだけです。

エラーの対処

undefined: grpc.SupportPackageIsVersion3

FAQにある通り、パッケージをバージョンアップすればなおります。
https://github.com/grpc/grpc-go#faq

# command-line-arguments
server/server.go:34: cannot use pingpongServer literal (type *pingpongServer) as type pingpong.PingpongServer in argument to pingpong.RegisterPingpongServer:
        *pingpongServer does not implement pingpong.PingpongServer (wrong type for Ping method)
                have Ping("context".Context, *pingpong.PingRequest) (*pingpong.PingResponse, error)
                want Ping("golang.org/x/net/context".Context, *pingpong.PingRequest) (*pingpong.PingResponse, error)

import "golang.org/x/net/context"とすればOKです。