環境:
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
目錄沒有添加到系統環境變量裡。
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";
注:
-
這個配置項目前版本盡量帶上,否則編譯時會報錯(M參數代表什麼沒有找到相關文檔)option go_package
Please specify either:
• a "go_package" option in the .proto source file, or
• a "M" argument on the command line.
-
代表在protoc編譯時,在option go_package = "./shannont/hello";
(見3.2)指定的目錄下自動生成shannont/hello檔案夾,同時在該檔案夾下生成的--go_out
檔案的包名是.pb.go
;hello
- 可以通過如下格式指定包名
,此時option go_package = "./shannont/hello;helloRename";
前含義同上,;
後表示生成的;
檔案的包名是.pb.go
helloRename
3.1.3 定義service和message
-
對應golang中的接口service
-
對應golang中的結構體message
// 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
檔案的package名還是由.pb.go
決定)option go_package
-
,針對--go-grpc_opt=paths=source_relative
檔案,作用同上_grpc.pb.go
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