我在我的一个应用程序(语音识别)中使用gRPC客户端服务器框架。我希望通过观察来澄清一些重要的事情。
1.当客户端没有填充可选数据字段时如何发送?
让我们看下面的例子:(假设使用了proto3,所以默认情况下所有字段都是可选的)
service NameStudent {
rpc GetRoll(Student) returns (Details) {}
}
#Student'd details
message Student{
int32 roll = 1;
string name = 2;
string gender = 4;
int32 age = 3;
DOB dateofbirth = 5;
}
#Students Date of Birth
message DOB {
int32 dd = 1;
int32 mm = 2;
int32 yy = 3;
}
#Parent's details
message Parent{
string parent =1;
}
#Students all details (includes student + parent)
message Details {
Student student = 1;
Parent parent = 4;
}
假设该服务(从客户输入)一些学生详细信息,例如roll,name和age,并返回该学生的(所有)详细信息
所以现在如果不是发送所有3个细节(即滚动,名称和年龄),也可以发送任何一个或两个细节,并且(逻辑上假设)服务有效。
在这种情况下,服务器是否会接收所有字段(对于省略的字段使用空白/ NULL)或客户端是否会发送省略的信息? (参见下面客户端发送的二进制数据表示)
// roll and name filled
// age is left blank
// gender and DOB are always sent blank from client
{
roll: 170012,
name: "John Doe",
age: ,
gender: "",
dateofbirth: {
dd: ,
mm: ,
yy:
}
}
要么
//only roll and name is sent and rest is just not sent
{
roll: 170012,
name: "John Doe"
}
2.可以为两个服务连接单个存根吗?
如果服务器提供2个服务而我正在制作客户端存根,我是否可以将2个通道从同一个存根连接到同一个服务器,访问它的2个不同服务?
问题1
看看this protobuf documentation。特别是:
对于proto3中的任何非重复字段或proto2中的可选字段,编码消息可能具有或不具有该字段编号的键值对。
但实际上,我观察到序列化中省略了具有默认值的可选字段。对protobuf进行反序列化时,解析器会将缺失的字段解释为默认值。您可以通过在Python protobuf对象上使用SerializeToString()
方法自己观察此行为。
问题2
将多个gRPC服务附加到同一服务器并与来自同一客户端通道的多个服务进行交互是绝对可能的。 gRPC使用HTTP2 paths来区分连接到同一服务器的多个服务。看看this gRPC Python generated code就是一个例子。 add_GreeterServicer_to_server
将用户定义的处理程序与路径/helloworld.Greeter/SayHello
相关联,然后存根用于在服务器上标识该服务。