0

我在我的一个应用程序(语音识别)中使用 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;
}

假设该服务获取(来自客户端的输入)一些学生详细信息,例如卷、姓名和年龄,并返回该学生的(所有)详细信息

所以现在如果不是发送所有 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 个不同服务?

4

1 回答 1

2

问题 1

看看这个 protobuf 文档。尤其:

对于 proto3 中的任何非重复字段或 proto2 中的可选字段,编码的消息可能具有也可能没有具有该字段编号的键值对。

但在实践中,我观察到在序列化中省略了具有默认值的可选字段。当 protobuf 被反序列化时,解析器会将缺失的字段解释为默认值。SerializeToString()您可以使用Python protobuf 对象上的方法自己观察此行为。

问题2

绝对可以将多个 gRPC 服务附加到同一台服务器,并与来自同一客户端通道的多个服务进行交互。gRPC 使用 HTTP2路径来区分连接到同一服务器的多个服务。看看这个 gRPC Python 生成的代码就是一个例子。add_GreeterServicer_to_server将用户定义的处理程序与 path 相关联/helloworld.Greeter/SayHello,然后存根使用它来标识服务器上的该服务。

于 2019-03-13T20:13:21.047 回答