通过一个简单的Demo快速入门gRPC
0x0. Demo结构
依赖参考:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 module grpc-example go 1.18 require ( github.com/golang/protobuf v1.5.2 // indirect golang.org/x/net v0.0.0-20201021035429-f5854403a974 // indirect golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4 // indirect golang.org/x/text v0.3.3 // indirect google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 // indirect google.golang.org/grpc v1.48.0 // indirect google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.2.0 // indirect google.golang.org/protobuf v1.28.1 // indirect )
0x1. 环境准备
安装依赖
1 go get google.golang.org/grpc
安装插件
1 2 go install google.golang.org/protobuf/cmd/protoc-gen-go@latest // 用于生成*.pb.go文件 go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest // 用于生成*_grpc.pb.go文件
0x2. 安装protoc编译器
protobuf GitHub:https://github.com/protocolbuffers/protobuf/releases
安装好之后将bin文件夹添加至环境变量
0x3. 编写proto文件 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 syntax = "proto3" ; option go_package = ".;api" ;service MessageSender { rpc Send(MessageRequest) returns (MessageResponse) {} } message MessageResponse { string responseSomething = 1 ; } message MessageRequest { string saySomething = 1 ; }
0x4. 生成代码 1 2 3 4 5 6 // 进入proto文件所在的文件夹 cd ./server/api// 自动生成代码 protoc --go_out=. --go-grpc_out=. *.proto // 自动生成代码 不生成mustEmbedUnimplemented*方法 protoc --go_out=. --go-grpc_opt=require_unimplemented_servers=false --go-grpc_out=. *.proto
运行过后,server/api
文件夹内会多两个文件,*pb.go
和*_grpc.pb.go
0x5. Client client/client.go
文件内容如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 package mainimport ( "context" "fmt" "google.golang.org/grpc" "grpc-example/server/api" "log" ) func main () { conn, err := grpc.Dial(fmt.Sprintf("127.0.0.1:%d" , 8082 ), grpc.WithInsecure()) if err != nil { log.Println(err) } defer conn.Close() client := api.NewMessageSenderClient(conn) send, err := client.Send(context.Background(), &api.MessageRequest{ SaySomething: "你好!" , }) if err != nil { log.Println(err) } fmt.Println(send.ResponseSomething) }
0x6. Server server/api/api.go
文件内容如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 package apiimport ( "context" "fmt" ) type ServerApi struct {} func (s *ServerApi) mustEmbedUnimplementedMessageSenderServer() { fmt.Println("implement me" ) } func (s *ServerApi) Send(ctx context.Context, request *MessageRequest) (*MessageResponse, error ) { return &MessageResponse{ResponseSomething: fmt.Sprintf("收到了,你说的是:%s" , request.GetSaySomething())}, nil }
server/server.go
文件内容如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 package mainimport ( "google.golang.org/grpc" "grpc-example/server/api" "log" "net" ) func main () { rpcServer := grpc.NewServer() api.RegisterMessageSenderServer(rpcServer, new (api.ServerApi)) listener, err := net.Listen("tcp" , ":8082" ) if err != nil { log.Fatal("服务监听端口失败" , err) } _ = rpcServer.Serve(listener) }
0x7. 运行 首先运行server/server.go
然后运行client/client.go
,运行效果如下:
1 2 3 4 5 6 7 GOROOT=D:\Applications\Go GOPATH= D:\Applications\Go\bin\go.exe build -o C:\Windows\Temp\GoLand\___go_build_grpc_example_client.exe grpc-example/client C:\Windows\Temp\GoLand\___go_build_grpc_example_client.exe 收到了,你说的是:你好! Process finished with the exit code 0