go使用grpc

lightTrace發表於2018-09-26
  1. 前言

最近需要使用grpc框架,然後到網上找資料,在此我強烈鄙視那些複製貼上的傢伙,第一步就錯了

go get google.golang.org/grpc 

這個根本安裝不起,是官方將程式碼遷移了,會報錯:

package google.golang.org/grpc: unrecognized import path "google.golang.org/grpc"(https fetch: Get https://google.golang.org/grpc?go-get=1: dial tcp 216.239.37.1:443: i/o timeout)

  1. 安裝grpc
    以下操作均在GOPATH下進行:
mkdir -p src/google.golang.org
cd src/google.golang.org
git clone https://github.com/grpc/grpc-go grpc
cd -
## 另外, grpc依賴的其他包需要一併下載
mkdir -p src/golang.org/x
cd src/golang.org/x
git clone https://github.com/golang/net
git clone https://github.com/golang/text
cd -
  1. 安裝grpc外掛
go get -u github.com/golang/protobuf/protoc-gen-go
## 不能直接訪問google.golang.org網址時, 從github下載然後放到google.golang.org目錄
mkdir -p src/google.golang.org/
cd src/google.golang.org
git clone https://github.com/google/go-genproto genproto
  1. 安裝protoc
    去這裡protoc下載

下載對應的protoc,我這裡下的是protoc-3.6.1-win32.zip

下好之後解壓就行,然後把bin裡面的protoc.exe加入到環境變數path中

  1. 執行go grpc的hello world
    grpc自帶一個示例:
$ cd $GOPATH/src/google.golang.org/grpc/examples/helloworld
  • 其中helloworld中的helloworld.proto是用來生成 gRPC 客戶端和伺服器端的介面,message 是代表資料結構(裡面可以包括不同型別的成員變數,包括字串、數字、陣列、字典……),service代表 RPC 介面。變數後面的數字是代表進行二進位制編碼時候的提示資訊,1~15 表示熱變數,會用較少的位元組來編碼。另外,支援匯入。預設所有變數都是可選的(optional),repeated 則表示陣列。主要 service rpc 介面只能接受單個 message 引數,返回單個 message;
  • helloworld.pb.go是通過protoc生成的
  • 然後green_client和green_server分別是grpc呼叫的客戶端和服務端

在helloworld目錄中:
執行:$ go run greeter_server/main.go

開啟另一個的終端,到相同的目錄下:
執行:$ go run greeter_client/main.go

你會看到Greeting: Hello world客戶端的輸出。

  • 更新rpc服務
  • 在helloworld.proto新增一個新的方法
// The greeting service definition.
service Greeter {
  // Sends a greeting
  rpc SayHello (HelloRequest) returns (HelloReply) {}
  // Sends another greeting
  rpc SayHelloAgain (HelloRequest) returns (HelloReply) {}
}

// The request message containing the user's name.
message HelloRequest {
  string name = 1;
}

// The response message containing the greetings
message HelloReply {
  string message = 1;
}
  • 生成grpc程式碼,即helloworld.pb.go
    在($GOPATH/src/google.golang.org/grpc/examples/helloworld)這個目錄,執行以下命令,將重新生成helloworld.pb.go:
$ protoc -I helloworld/ helloworld/helloworld.proto --go_out=plugins=grpc:helloworld

可以觀察到helloworld.pb.go已經多了一個SayHelloAgain的方法

  • 更新並重新執行程式
    編輯greeter_server/main.go並新增以下函式:

    func (s *server) SayHelloAgain(ctx context.Context, in *pb.HelloRequest) (*pb.HelloReply, error) {
    return &pb.HelloReply{Message: "Hello again " + in.Name}, nil
    }

更新客戶端
編輯greeter_client/main.go將以下程式碼新增到主函式的最後。

r, err = c.SayHelloAgain(context.Background(), &pb.HelloRequest{Name: name})
if err != nil {
        log.Fatalf("could not greet: %v", err)
}
log.Printf("Greeting: %s", r.Message)

執行伺服器

$ go run greeter_server/main.go

在不同的終端上執行客戶端

$ go run greeter_client/main.go

輸出:

Greeting: Hello world
Greeting: Hello again world

相關文章