GolagnでgRPCを使ってみる
環境
Windows 10 Pro
Golang 1.12
GO111MODULE=on
成果物
手順
下準備
とりあえずプロジェクト用のディレクトリを作ります
そこでgo mod initして
go get google.golang.org/grpcでgrpcをダウンロードしておきます
go.modにrequire google.golang.org/grpc {version}が追加されてればOK
protocol bufferのファイル作成
protoってディレクトリを作り、そこに移動
{package name}.protoというファイルを作成する
別にファイル名はなんでもいい
今回はgrpc-tutorial.protoってファイル名にしてる
go getしたgrpcのなかに、examples/helloworld/helloworld/helloworld.protoってファイルがあるので、これの中身をコピー
packageの部分だけ独自のものに変えて、あと要らないコメントは消せばOK
Golangのソースを生成
プロジェクトの直下に戻って、protoc -I proto/ proto/grpc-tutorial.proto --go_out=plugins=grpc:proto
登場するprotoはすべてディレクトリを指してます
なので、proto分かりにくいよ!ってことなら、他の名前で大丈夫です
examples/helloworldではhelloworldになってて余計にわかりにくい
grpc-tutorial.pb.goが生成されていたら成功
あり得るエラー
grpc-tutorial/: No such file or directory
grpc-tutorial.proto: File does not reside within any path specified using --proto_path (or -I). 以下略
-Iでprotoのpathを指定してるのでそこで間違っているか、protoファイルの相対パスが間違っていて、protoファイルがないよって言われてる。
--go_out=plugins=grpc:grpc-tutorial
grpc-tutorialが出力先を指定してる。このディレクトリがないよって言われてる
生成されたファイルにinterfaceの定義がない
protoc-gen-go.exeが用意できてないか、スペルミスしてるかのどちらか
私の場合は、pluginsのところをpluginと書いていて撃沈
Serverサイドの作成
プロジェクトルートにserverディレクトリを作って、そこにmain.goを作ります
interfaceGreeterServerを実装したstructserverを作ります
code:golang
type server struct{}
func (s *server) SayHello(ctx context.Context, in *grpc_tutorial.HelloRequest) (*grpc_tutorial.HelloReply, error) {
log.Printf("Received: %v", in.Name)
return &grpc_tutorial.HelloReply{Message: "Hello " + in.Name}, nil
}
送信されてきたNameにHelloをつけて返すだけですね
funcmainはこのサーバを叩き起こすだけ
code:golang
func main() {
lis, err := net.Listen("tcp", ":5432")
if err != nil {
log.Fatalf("failed to listen: %v", err)
}
s := grpc.NewServer()
grpc_tutorial.RegisterGreeterServer(s, &server{})
if err := s.Serve(lis); err != nil {
log.Fatalf("failed to serve: %v", err)
}
}
5432ポートを使ってるけど、これに決まりがあるわけじゃないので都合がいいのを適当にどうぞ
Clientサイドの作成
クライアントサイドは本当にただ叩くだけです
code:golang
const (
address = "localhost:5432"
defaultName = "world"
)
func main() {
conn, err := grpc.Dial(address, grpc.WithInsecure())
if err != nil {
log.Fatalf("did not connect: %v", err)
}
defer conn.Close()
c := grpc_tutorial.NewGreeterClient(conn)
// Contact the server and print out its response.
name := defaultName
if len(os.Args) > 1 {
}
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
defer cancel()
r, err := c.SayHello(ctx, &grpc_tutorial.HelloRequest{Name: name})
if err != nil {
log.Fatalf("could not greet: %v", err)
}
log.Printf("Greeting: %s", r.Message)
}
動かしてみる!!
サーバの起動
プロジェクトルートでgo run server/main.go
クライアントの実行
プロジェクトルートでgo run client/main.go
code:bash
$ go run client/main.go
2019/05/23 23:22:51 Greeting: Hello world
プロジェクトルートでgo run client/main.go hogehoge
code:bash
$ go run client/main.go hogehoge
2019/05/23 23:23:14 Greeting: Hello hogehoge
おわり
Hello Worldするだけだとまだ恩恵をかんじれなかった
チャットみたいなのを実装してみると色々わかってくるのかも
最終更新日: 2019/05/23