如何在 gRPC 中将数据从客户端发送到(多服务)服务器
How data is sent from client to (multi-service) server in gRPC
我在我的一个应用程序(语音识别)中使用 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;
}
假设服务接受(来自客户端的输入)一些学生的详细信息,例如学名、姓名和年龄,以及return 该学生的(所有)详细信息
所以现在如果不是发送所有 3 个详细信息(即角色、姓名和年龄),甚至任何一个或两个详细信息也可以发送并且(逻辑上假设)服务工作。
在这种情况下,服务器会接收所有字段(blanks/NULLs 用于省略的字段)还是客户端根本不会发送 省略的信息? (见下文 二进制数据的表示 从客户端发送)
// 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。特别是:
For any non-repeated fields in proto3, or optional fields in proto2,
the encoded message may or may not have a key-value pair with that
field number.
但在实践中,我观察到在序列化中省略了具有默认值的可选字段。当 protobuf 被反序列化时,解析器会将缺失的字段解释为默认值。您可以通过在 Python protobuf 对象上使用 SerializeToString()
方法自己观察此行为。
问题二
绝对有可能将多个 gRPC 服务附加到同一个服务器,并从同一个客户端通道与多个服务进行交互。 gRPC 使用 HTTP2 paths to differentiate between multiple services attached to the same server. Take a look at this gRPC Python generated code 作为一个例子。 add_GreeterServicer_to_server
将用户定义的处理程序与路径 /helloworld.Greeter/SayHello
相关联,然后存根使用该路径来识别服务器上的该服务。
我在我的一个应用程序(语音识别)中使用 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;
}
假设服务接受(来自客户端的输入)一些学生的详细信息,例如学名、姓名和年龄,以及return 该学生的(所有)详细信息
所以现在如果不是发送所有 3 个详细信息(即角色、姓名和年龄),甚至任何一个或两个详细信息也可以发送并且(逻辑上假设)服务工作。
在这种情况下,服务器会接收所有字段(blanks/NULLs 用于省略的字段)还是客户端根本不会发送 省略的信息? (见下文 二进制数据的表示 从客户端发送)
// 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。特别是:
For any non-repeated fields in proto3, or optional fields in proto2, the encoded message may or may not have a key-value pair with that field number.
但在实践中,我观察到在序列化中省略了具有默认值的可选字段。当 protobuf 被反序列化时,解析器会将缺失的字段解释为默认值。您可以通过在 Python protobuf 对象上使用 SerializeToString()
方法自己观察此行为。
问题二
绝对有可能将多个 gRPC 服务附加到同一个服务器,并从同一个客户端通道与多个服务进行交互。 gRPC 使用 HTTP2 paths to differentiate between multiple services attached to the same server. Take a look at this gRPC Python generated code 作为一个例子。 add_GreeterServicer_to_server
将用户定义的处理程序与路径 /helloworld.Greeter/SayHello
相关联,然后存根使用该路径来识别服务器上的该服务。