1 下载插件
$ go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.28$ go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.2
2 添加到环境变量
vi ~/.profile, 添加此行到文件末尾
export PATH=$PATH:$GOPATH/bin
3 proto文件
syntax = "proto3";// _grpc.pb.go文件生成路径为./ ; 生成的go文件package名为protooption go_package = "./;proto";service Greeter {rpc SayHello (HelloRequest) returns (HelloReply);}message HelloRequest {string name = 1;}message HelloReply {string message = 1;}
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
// 去除proto中的json的omitemptymac: sed -i "" 's/,omitempty//g' *.pb.golinux: sed -i 's/,omitempty//g' *.pb.go
go get github.com/srikrsna/protoc-gen-gotagprotoc --gotag_out=auto="json-as-camel":. user.proto

生成了两个文件
- 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) }
<a name="JWa5o"></a># 6 client.go```gopackage mainimport ("context""google.golang.org/grpc""google.golang.org/grpc/credentials/insecure""log""testgrpc/proto""time")func main() {addr := "localhost:8080"name := "world"// Set up a connection to the server.conn, err := grpc.Dial(addr, grpc.WithTransportCredentials(insecure.NewCredentials()))if err != nil {log.Fatalf("did not connect: %v", err)}defer conn.Close()c := proto.NewGreeterClient(conn)// Contact the server and print out its response.ctx, cancel := context.WithTimeout(context.Background(), time.Second)defer cancel()r, err := c.SayHello(ctx, &proto.HelloRequest{Name: name})if err != nil {log.Fatalf("could not greet: %v", err)}log.Printf("Greeting: %s", r.GetMessage())}
