服务编译成功,但未生成消息结构 - gRPC/Go

Service compiling successfully, but message structs not generating - gRPC/Go

我使用 gRPC/protobufs 作为我的客户端和服务器之间通信的协议,两者都是用 go 编写的。我能够 运行 下面显示的命令毫无问题地生成 cards.pb.go (服务器)和 cards_grpc.pb.go (客户端)文件。服务器文件运行良好,没有任何问题。但是,客户端文件似乎无法访问我在 cards.proto 文件中定义的 message 项。我的服务以及我的客户端代码需要定义的消息结构才能调用服务方法,但我不确定我缺少什么。

这是我要 运行ning 的命令:

protoc -I="./protos" \
--go_out=plugins=grpc:./server \
--go-grpc_out=./client \
protos/*.proto 

这是我的项目文件结构:

|-- client
    |-- protos (generated protobufs for client)
        |-- cards_grpc.pb.go (this compiled successfully, but structs representing my messages cannot be found)
|-- protos (This is where the proto files are defined)
    |-- cards.proto
|-- server
    |-- protos (generated protobufs for server)
        |-- cards.pb.go (this is working perfectly, has compiled services and messages)

注意:我在我的cards.proto文件中定义了option go_package = "./protos";,这就是为什么生成的文件输出到*/protos/*.pb.go个位置

所以你在这里没有为客户端代码生成任何 protobuf 相关代码,只有 gRPC 一个。为了生成您要查找的结构,请使用以下命令:

protoc -I./protos        \
  --go_out=./server      \
  --go-grpc_out=./server \
  --go_out=./client      \
  --go-grpc_out=./client \
  protos/*.proto 

--go_out生成protobuf的go代码,--go-grpc_out生成gRPC的go代码。

另一件事,--go_out=plugins=grpc are not supported in go anymore。你应该使用 --go-grpc_out.

更多推荐

我强烈建议与客户端和服务器共享 proto 目录(如果可能),这会限制由于未同步的 Proto 文件而导致的潜在错误。

所以你会得到类似的东西:

|-- client
|-- protos
    |-- cards.proto
    |-- cards_grpc.pb.go
    |-- cards.pb.go
|-- server

然后双方访问所需的文件。

其次,如果你正在使用 Go 模块,我建议你使用 go_package 如下:

option go_package = "${YOUR_MODULE}/protos"

然后生成如下代码:

protoc -Iprotos \
  --go_opt=module=${YOUR_MODULE} --go_out=. \
  --go-grpc_opt=module=${YOUR_MODULE} --go-grpc_out=. \
  protos/*.proto

请注意 --go_out--go-grpc_out.。这会将项目的根映射到模块名称,这将通过将模块名称删除到 go_package 选项来在 protos 目录中生成代码。然后你就可以像这样在你的代码中访问这个生成的代码:

import (
    pb "${YOUR_MODULE}/protos"
)

澄清

为了清楚go_package,你需要明白一件事:protobuf包和go_package不是一回事,前者定义的包只能在.proto文件中使用,后者在你的 go 文件中定义了 package ... 。一个例子:

对于 Protobuf 包

file1.proto

//...
package protos;

message Test {}
//...

file2.proto

//...
//no package definition

message Test2 {
    protos.Test a_test = 1;
}
//...

对于go_package

go.mod

module my_module

file1.proto(位于:${ROOT}/protos)

//...
option go_package = "my_module/protos"

message Test {}
//...

protoc -I./protos        \
  --go_out=./server      \
  --go-grpc_out=./server \
  --go_out=./client      \
  --go-grpc_out=./client \
  protos/file1.proto 

main.go

package main

import (
    pb "my_module/proto"
)

func main() {
    var test pb.Test;
}