前言
gRPC 是 Google 發起的一個高效能的、開源的遠端程序呼叫(Remote Procedure Call)框架。此框架基於 HTTP/2 協定傳輸,使用 Protocol Buffers 作為介面描述語言。
一個簡單的 Protocol Buffers 語法如下:
1 2 3 4 5
| message Person { required string name = 1; required int32 id = 2; optional string email = 3; }
|
做法
建立專案。
1 2 3
| mkdir grpc-go-example cd grpc-go-example go mod init
|
安裝套件
安裝 grpc
套件。
1
| go get -u google.golang.org/grpc
|
安裝 protoc-gen-go
套件。
1
| go get -u github.com/golang/protobuf/protoc-gen-go
|
定義服務
新增 hello.proto
檔:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| syntax = "proto3";
option go_package = ".;hello";
service HelloService { rpc SayHello (HelloRequest) returns (HelloResponse); }
message HelloRequest { string greeting = 1; }
message HelloResponse { string reply = 1; }
|
使用以下指令,生成 hello.pb.go
檔:
1
| protoc --go_out=plugins=grpc:. hello.proto
|
實作服務端
在 server
資料夾新增 main.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 28 29 30 31 32 33 34
| package main
import ( "context" pb "github.com/memochou1993/grpc-go-example" "google.golang.org/grpc" "log" "net" )
type service struct { pb.UnimplementedHelloServiceServer }
func (s *service) SayHello(ctx context.Context, r *pb.HelloRequest) (*pb.HelloResponse, error) { log.Printf("Request received: %s", r.GetGreeting()) return &pb.HelloResponse{Reply: "Hello, " + r.GetGreeting()}, nil }
func main() { addr := "127.0.0.1:8080" ln, err := net.Listen("tcp", addr) if err != nil { log.Fatalln(err.Error()) }
s := grpc.NewServer() pb.RegisterHelloServiceServer(s, new(service)) if err := s.Serve(ln); err != nil { log.Fatalln(err.Error()) } }
|
使用終端機執行服務端程式:
實作客戶端
在 client
資料夾新增 main.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 28 29 30
| package main
import ( "context" pb "github.com/memochou1993/grpc-go-example" "google.golang.org/grpc" "log" "time" )
func main() { ctx, cancel := context.WithTimeout(context.Background(), time.Second) defer cancel()
addr := "127.0.0.1:8080" conn, err := grpc.DialContext(ctx, addr, grpc.WithInsecure(), grpc.WithBlock()) if err != nil { log.Fatalln(err.Error()) } defer conn.Close()
c := pb.NewHelloServiceClient(conn) r, err := c.SayHello(ctx, &pb.HelloRequest{Greeting: "World!"}) if err != nil { log.Fatalln(err.Error()) } log.Printf("Response received: %s", r.GetReply()) }
|
使用終端機執行客戶端程式:
1 2
| go run client/main.go Response received: Hello, World!
|
程式碼