使用Protocol Buffers在ZeroMQ中实现RPC

5

我有一个简单的客户端和服务器设置。客户端想要使用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);
}

什么是最好的方法?或者至少使用一种方法的代价是什么,相比之下又有哪些优劣呢?

1个回答

5

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

message InputParameters{
    req oneof
    {
        InputParametersA a = 1;
        InputParametersB b = 2;
    }
}
message InputParametersA
{
    bool block = 1;
    float temperature = 2;
}
message InputParametersB
{
    <more fields>
}

那样你只发送InputParameters消息。调用的方法由InputParameters.req中包含的InputParametersA(意味着应该调用方法A)或InputParmetersB(用于方法B)决定。
这避免了解析字符串以确定方法名称(高度容易出错),而是给您一个枚举来切换(req字段的可能内容)。根据您使用的GPB实现(C ++等),如果您的switch语句未充分涵盖该枚举的所有值,则甚至可能在编译时获得警告。
这也意味着确定应将哪些字段传递给方法没有问题;您将InputParameters.req.a传递到方法A或.b传递到方法B。没有必要将它们分解为单独的参数,只需将整个内容作为单个参数传递即可。
您可以通过相同的方式定义不同的返回类型,将它们全部通过单个oneof返回。 替代方案 现在,如果您正在使用ASN.1(这在概念上与GPB相同),则可以对消息字段的值和/或大小设置约束(请参见此处PDF第13章)。这样,您就可以自动执行参数验证,仅在ASN.1模式中定义。GPB缺乏值/大小约束是一个显眼的遗漏。
请参见这里(概述)这里(C / C ++免费模式编译器看起来不错)这里(PDF参考手册)
ASN.1在其传输格式中具有更强的类型(如果使用BER编码)。可以询问线路位流以查找它包含的消息类型。因此,无需像GPB一样将所有可能的消息都包装到单个oneof中。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接