天天看點

【Golang | gRPC】使用protoc編譯.proto檔案1. 安裝protoc2. 安裝針對go的protoc插件3. 實踐4. 總結

環境:

Golang: go1.18.2 windows/amd64

protoc:libprotoc 3.21.1

1. 安裝protoc

使用

protoc

編譯.proto檔案,首先需要正确安裝

protoc

編譯器。如果使用預編譯的二進制檔案方式安裝,注意添加環境變量,具體可以參考【Golang | gRPC】protocol buffer compiler\protoc的安裝

2. 安裝針對go的protoc插件

protoc本身并不支援Golang,需要額外安裝對應的插件

方法1,使用

go install <module>@latest

安裝

go install google.golang.org/protobuf/cmd/[email protected]
go install google.golang.org/grpc/cmd/[email protected]
           

方法2,在一個已經包含go.mod檔案的項目裡使用

go get <module>

go get google.golang.org/protobuf/cmd/protoc-gen-go
go get google.golang.org/grpc/cmd/protoc-gen-go-grpc
           

安裝成功後,會在

$GOPATH/bin

目錄下生成兩個2進制檔案

  • protoc-gen-go

  • protoc-gen-go-grpc

注:

這時候執行

protoc --go_out=. --go-grpc_out=. *.proto

時,可能出現

--go_out: protoc-gen-go: Plugin failed with status code 1

的報錯,這是由于

$GOPATH/bin

目錄沒有添加到系統環境變量裡。

【Golang | gRPC】使用protoc編譯.proto檔案1. 安裝protoc2. 安裝針對go的protoc插件3. 實踐4. 總結

3. 實踐

3.1 準備一個.proto檔案

3.1.1 建立gRPC項目,使用

go mod init

初始化,建立pb檔案夾,建立hello.proto檔案

3.1.2 指定

syntax

,

package

,

option go_package

,分别代表protobuf版本,包名,編譯生成的

.pb.go

檔案目錄

syntax = "proto3";
package pb;
option go_package = "./shannont/hello";
           

注:

  • option go_package

    這個配置項目前版本盡量帶上,否則編譯時會報錯(M參數代表什麼沒有找到相關文檔)
Please specify either:
        • a "go_package" option in the .proto source file, or
        • a "M" argument on the command line.
           
  • option go_package = "./shannont/hello";

    代表在protoc編譯時,在

    --go_out

    (見3.2)指定的目錄下自動生成shannont/hello檔案夾,同時在該檔案夾下生成的

    .pb.go

    檔案的包名是

    hello

  • 可以通過如下格式指定包名

    option go_package = "./shannont/hello;helloRename";

    ,此時

    ;

    前含義同上,

    ;

    後表示生成的

    .pb.go

    檔案的包名是

    helloRename

3.1.3 定義service和message

  • service

    對應golang中的接口
  • message

    對應golang中的結構體
// The greeter service definition.
service Greeter {
  // Sends a greeting
  rpc SayHello (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;
}
           

3.2 使用protoc編譯

gRPC/pb

目錄下使用如下指令進行編譯

protoc --go_out=. --go-grpc_out=. ./hello.proto

,生成對應的

.pb.go

_grpc.pb.go

兩個檔案,前者主要是對message生成對應的結構體和方法,後者生成

gRPC

,主要是對service生成對應的interface和方法

  • go_out=.

    指定生成的

    pb.go

    檔案所在目錄(如果沒有該目錄,需要手動提前建立),

    .

    代表目前protoc執行目錄,結合

    .proto

    檔案中的

    option go_package

    ,其最終的生成檔案目錄為

    go_out指定目錄/go_package指定目錄

  • go-grpc_out

    針對

    _grpc.pb.go

    檔案,作用同上
  • 另外官網文檔裡還有一個

    --go_opt=paths=source_relative

    ,其含義代表生成的

    .pb.go

    檔案路徑不依賴于

    .proto

    檔案中的

    option go_package

    配置項,直接在

    go_out

    指定的目錄下生成

    .pb.go

    檔案(

    .pb.go

    檔案的package名還是由

    option go_package

    決定)
  • --go-grpc_opt=paths=source_relative

    ,針對

    _grpc.pb.go

    檔案,作用同上
    【Golang | gRPC】使用protoc編譯.proto檔案1. 安裝protoc2. 安裝針對go的protoc插件3. 實踐4. 總結
    【Golang | gRPC】使用protoc編譯.proto檔案1. 安裝protoc2. 安裝針對go的protoc插件3. 實踐4. 總結

4. 總結

  • 子產品

    github.com/golang/protobuf

    google.golang.org/protobuf"

    取代
  • 目前版本編譯時,之前的方法

    protoc --go_out=plugins=grpc:. *.proto

    不再使用,轉而用

    protoc --go_out=. --go-grpc_out=. ./hello.proto

    代替。有如下提示
PS C:\Users\tianwanshan\GolandProjects\GolangLearning\RPC\gRPC\pb> protoc --go_out=plugins=grpc:. *.proto
--go_out: protoc-gen-go: plugins are not supported; use 'protoc --go-grpc_out=...' to generate gRPC