1 下载插件

  1. $ go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.28
  2. $ go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.2

2 添加到环境变量

vi ~/.profile, 添加此行到文件末尾

  1. export PATH=$PATH:$GOPATH/bin

source ~/.profile

3 proto文件

  1. syntax = "proto3";
  2. // _grpc.pb.go文件生成路径为./ ; 生成的go文件package名为proto
  3. option go_package = "./;proto";
  4. service Greeter {
  5. rpc SayHello (HelloRequest) returns (HelloReply);
  6. }
  7. message HelloRequest {
  8. string name = 1;
  9. }
  10. message HelloReply {
  11. string message = 1;
  12. }

4 根据proto生成go文件

(1) protoc命令详解

protoc -I=. —go_out=./ —go-grpc_out=./ /proto/user.proto

  • I: 指定proto文件和导入proto文件的搜索根路径, 可以指定多个

    若I是/home/ws/code, 导包语句是 import “app/user/rpc/user.proto” 那么导入的包的全路径就是/home/ws/code/app/user/rpc/user.proto

等价于—proto_path=.

  • go_out: 指定pb.go代码的生成位置

    —go_out 参数的写法是,参数之间用逗号隔开, 最后加上冒号来指定代码目录架构的生成位置

例如:—go_out=plugins=grpc,paths=import:.
paths 参数有两个选项,import 和 source_relative 。

  • 默认为 import:. ,代表把pb.go生成到option go_package里指定的目录
  • source_relative:. 代表把pb.go生成到和proto同级

pugins=grpc 现在已经不支持了, 要改用go-grpc_out

  • go-grpc_out: 指定_grpc.pb.go代码(stub)的生成位置

若为./, 则把_grpc.pb.go生成到option go_package里指定的目录

(2) 去除omitempty

  1. // 去除proto中的json的omitempty
  2. mac: sed -i "" 's/,omitempty//g' *.pb.go
  3. linux: sed -i 's/,omitempty//g' *.pb.go
  1. go get github.com/srikrsna/protoc-gen-gotag
  2. protoc --gotag_out=auto="json-as-camel":. user.proto

image.png
生成了两个文件

  • hello.pb.go: 定义了协议, 即请求与响应的消息结构
  • hello_grpc.pb.go: 定义了stub, 即grpc的client stub和server stub

    5 server.go

    ```go package main

import ( “context” “google.golang.org/grpc” “net” “testgrpc/proto” )

type Server struct { proto.UnimplementedGreeterServer }

func (s Server) SayHello(ctx context.Context, request proto.HelloRequest) (*proto.HelloReply, error) { return &proto.HelloReply{ Message: “hello” + request.Name, }, nil }

func main() { g := grpc.NewServer() proto.RegisterGreeterServer(g, &Server{}) listener, err := net.Listen(“tcp”, “:8080”) if err != nil { panic(“failed to listen: “ + err.Error()) } _ = g.Serve(listener) }

  1. <a name="JWa5o"></a>
  2. # 6 client.go
  3. ```go
  4. package main
  5. import (
  6. "context"
  7. "google.golang.org/grpc"
  8. "google.golang.org/grpc/credentials/insecure"
  9. "log"
  10. "testgrpc/proto"
  11. "time"
  12. )
  13. func main() {
  14. addr := "localhost:8080"
  15. name := "world"
  16. // Set up a connection to the server.
  17. conn, err := grpc.Dial(addr, grpc.WithTransportCredentials(insecure.NewCredentials()))
  18. if err != nil {
  19. log.Fatalf("did not connect: %v", err)
  20. }
  21. defer conn.Close()
  22. c := proto.NewGreeterClient(conn)
  23. // Contact the server and print out its response.
  24. ctx, cancel := context.WithTimeout(context.Background(), time.Second)
  25. defer cancel()
  26. r, err := c.SayHello(ctx, &proto.HelloRequest{Name: name})
  27. if err != nil {
  28. log.Fatalf("could not greet: %v", err)
  29. }
  30. log.Printf("Greeting: %s", r.GetMessage())
  31. }