英文:
Using structs in oneOf field in Protocol Buffers v3 via Go
问题
尝试将 Protocol Buffers v3 和 Go 结合使用(对两者都不熟悉)。
example.proto
syntax = "proto3";
package test;
import "google/protobuf/timestamp.proto";
message Metadata {
uint64 userID = 2;
google.protobuf.Timestamp time= 3;
}
// 当用户退出 Glory 时进行签退
message SignOff {
Metadata metadata =1;
}
// 当用户登录 Glory 时进行签到
message SignOn {
Metadata metadata =1;
}
message EventWrapper {
oneof event {
SignOff signOff = 1;
SignOn signOn = 2;
}
}
使用 protoc
进行转换并在 Go 中使用:
now, _ := ptypes.TimestampProto(time.Now())
event := &pb_test.EventWrapper{
Event: &pb_test.EventWrapper_SignOn{
SignOn: &pb_test.SignOn{
Metadata: &pb_test.Metadata{
UserID: 1234,
Time: now,
},
},
},
}
protoBytes, err := proto.Marshal(event)
if err != nil {
log.Fatal(err)
}
log.Println(len(protoBytes) == 0)
jsonBytes, _ = json.MarshalIndent(event, "", "\t")
log.Println(string(jsonBytes))
输出显示 JSON 是正确的,但 Protobuf 编码的字节数组为空。
{
"Event": {
"SignOn": {
"metadata": {
"userID": 1234,
"time": {
"seconds": 1491143507,
"nanos": 654053400
}
}
}
}
}
意图是通过 gRPC 在网络上传输这些对象的数组(repeated *EventWrapper
),但目前单个对象无法正常工作。Protobuf 的语言指南没有提到不允许使用结构体。我是否遗漏了什么?
英文:
So trying to using Protocol Buffers v3 and Go together (new to both).
example.proto
syntax = "proto3";
package test;
import "google/protobuf/timestamp.proto";
message Metadata {
uint64 userID = 2;
google.protobuf.Timestamp time= 3;
}
//SignOff when user logs out of Glory
message SignOff {
Metadata metadata =1;
}
//SignOn when user logs into Glory
message SignOn {
Metadata metadata =1;
}
message EventWrapper {
oneof event {
SignOff signOff = 1;
SignOn signOn = 2;
}
}
Converting with protoc
and using in Go
now, _ := ptypes.TimestampProto(time.Now())
event := &pb_test.EventWrapper{
Event: &pb_test.EventWrapper_SignOn{
SignOn: &pb_test.SignOn{
Metadata: &pb_test.Metadata{
UserID: 1234,
Time: now,
},
},
},
}
protoBytes, err := proto.Marshal(event)
if err != nil {
log.Fatal(err)
}
log.Println(len(protoBytes) == 0)
jsonBytes, _ = json.MarshalIndent(event, "", "\t")
log.Println(string(jsonBytes))
The output shows the JSON is right but the protobuf encoded byte array is empty.
{
"Event": {
"SignOn": {
"metadata": {
"userID": 1234,
"time": {
"seconds": 1491143507,
"nanos": 654053400
}
}
}
}
}
The intent is the have a array of these (repeated *EventWrapper
) to send along the wire via gRPC, but the individual ones don't work at the moment. The protobuf Language Guide doesn't say anything about structs not being allowed. Is there something I'm missing?
答案1
得分: 2
协议缓冲区文档中没有说明oneof
不能是结构体,实际上,示例为union
字段生成了结构体。
我建议使用gogo,我个人在之前的商业项目中使用过。具体来说,使用protoc-gen-gogoslick
。
请参考这个部分来安装必要的包,然后对你的项目运行以下命令:
protoc --gogoslick_out=Mgoogle/protobuf/timestamp.proto=github.com/gogo/protobuf/types:. example.proto
英文:
Nothing in the Protocol Buffer documentation indicates oneof
cannot be structs, and in fact the example generates structs for a union
field.
I recommend using gogo, which I have personally used for previous commercial projects. Specifically, use protoc-gen-gogoslick
See this section for installing the necessary packages, then run the following for your project
protoc --gogoslick_out=Mgoogle/protobuf/timestamp.proto=github.com/gogo/protobuf/types:. example.proto
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论