Protocol buffers 使用协议缓冲区在ZeroMQ中实现RPC

Protocol buffers 使用协议缓冲区在ZeroMQ中实现RPC,protocol-buffers,zeromq,Protocol Buffers,Zeromq,我有一个简单的设置,一个客户端和一个服务器。客户机希望在服务器中使用ZeroMQ执行通信方法。我将使用REQ和REP套接字,因为它们适用于这个用例。然而,我对protobuf的定义有疑问。我认为这两个选项可用于实现目标: message ControlService{ string control = 1; int32 serverId = 2; bool block = 3; double temperature = 4; } 其中“control”包含要远程

我有一个简单的设置,一个客户端和一个服务器。客户机希望在服务器中使用ZeroMQ执行通信方法。我将使用REQ和REP套接字,因为它们适用于这个用例。然而,我对protobuf的定义有疑问。我认为这两个选项可用于实现目标:

message ControlService{
    string control = 1;
    int32 serverId = 2;
    bool block = 3;
    double temperature = 4;
}
其中“control”包含要远程执行的方法的名称。另一种选择是:

message InputParameters{
    int32 serverId = 1;
    bool block = 2;
    double temperature = 3;
}
message Empty{

}
service ControlService{
    rpc control (InputParameters) returns (Empty);
}

最好的方法是什么?或者至少,使用一种方法而不是另一种方法的权衡是什么

不要那样做。有一个信息:

message InputParameters{
    req oneof
    {
        InputParametersA a = 1;
        InputParametersB b = 2;
    }
}
message InputParametersA
{
    bool block = 1;
    float temperature = 2;
}
message InputParametersB
{
    <more fields>
}
消息输入参数{
请求其中一个
{
输入参数a=1;
输入参数b=2;
}
}
消息输入参数a
{
布尔块=1;
浮子温度=2;
}
消息输入参数b
{
}
这样,您只发送InputParameters消息。要调用的方法由InputParameters.req是否包含InputParametersA(意味着应该调用方法A)或InputParmetersB(对于方法B)决定

这避免了解析字符串以确定方法名称(极易出错),而是为您提供了一个要打开的枚举(req字段的可能内容)。根据使用的GPB实现(C++等),如果switch语句没有充分覆盖该枚举的所有值,甚至可能会收到编译时警告

这也意味着在确定哪些字段应该传递给方法时没有问题;您可以将InputParameters.req.a传递给方法a,也可以将InputParameters.b传递给方法b。对于一个方法,不需要将它们分解为单独的参数,只需将整个过程作为单个参数传递即可

您可以用相同的方式定义不同的返回类型,通过一个
返回

备选方案

现在,如果您使用的是ASN.1(在概念上与GPB是同一种类型的东西),您可以对消息字段的值和/或大小设置约束(请参阅)。这样您就可以自动执行参数验证,仅在ASN.1模式中定义。GPB中缺少值/大小约束是一个明显的遗漏

看一看,然后

ASN.1的有线格式具有更强的键入功能(如果您使用BER编码)。可以查询有线比特流以了解它包含的消息类型。因此,不需要像GPB那样将所有可能的消息包装成一个
或一个