[英]More efficient way to set a oneof request in gRPC/proto3
在 PHP 客户端和 Python 服务器上具有此 proto3 模式:
service GetAnimalData{
rpc GetData (AnimalRequest) returns (AnimalData) {}
}
message AnimalRequest {
OneOfAnimal TypeAnimal = 1;
}
message AnimalData {
repeated int32 data = 1;
}
message OneOfAnimal {
oneof animal_oneof {
CAT cat = 1;
DOG dog = 2;
}
}
message CAT{
int32 p = 1;
int32 d = 2;
int32 q = 3;
}
message DOG{
int32 p = 1;
int32 d = 2;
int32 q = 3;
int32 p2 = 4;
int32 d2 = 5;
int32 q2 = 6;
}
为了设置来自 PHP 客户端的请求,我需要执行以下操作:
CAT
OneOfAnimal
设置为CAT
AnimalRequest.TypeAnimal
设置为OneOfAnimal
是否有 proto3 的架构,我可以直接将CAT
或DOG
object 设置为我的AnimalRequest.TypeAnimal
笼统; 不,不是。
在某些非常具体的情况下,答案是“是” - 例如,protobuf-net(.NET 中的“代码优先”protobuf 实现)恰好以这种方式实现 inheritance,因此您可以使用:
[ProtoContract]
public class AnimalRequest {
[ProtoMember(1)] public Animal Animal {get;set;}
}
[ProtoContract]
[ProtoInclude(1, typeof(Cat))]
[ProtoInclude(2, typeof(Dog))]
class Animal {} // acts identically to your OneOfAnimal message type
[ProtoContract]
class Cat {
[ProtoMember(1)] public int P {get;set;}
[ProtoMember(2)] public int D {get;set;}
[ProtoMember(3)] public int Q {get;set;}
}
[ProtoContract]
class Dog {
[ProtoMember(1)] public int P {get;set;}
[ProtoMember(2)] public int D {get;set;}
[ProtoMember(3)] public int Q {get;set;}
[ProtoMember(4)] public int P2 {get;set;}
[ProtoMember(5)] public int D2 {get;set;}
[ProtoMember(6)] public int Q2 {get;set;}
}
然后你使用:
var result = svc.GetData(
new AnimalRequest { Animal = new Dog { P = 42, ... Q2 = 19 } }
);
它会以完全相同的方式工作——发送相同的字节; 本质上,protobuf-net 将 inheritance 视为oneof
(在类型层次结构中的每个级别)。
但是:因为.proto
旨在以非常通用的“最小公分母”方式工作,所以 .proto 本身没有 inheritance 的概念.proto
所以:你不能从.proto
或谷歌库中做到这一点。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.