在 ZeroMQ 中使用 Protocol Buffers 实现 RPC [英] Using Protocol Buffers for implementing RPC in ZeroMQ

查看:47
本文介绍了在 ZeroMQ 中使用 Protocol Buffers 实现 RPC的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a simple setup of one client and one server. The client wants to execute a method in the server using ZeroMQ for communications. I am going to use the REQ and REP sockets because they are suitable for this use case. Nevertheless I have a doubt about the protobuf definitions. I think these two options can be used for achieving the goal:

message ControlService{
    string control = 1;
    int32 serverId = 2;
    bool block = 3;
    double temperature = 4;
}

其中control"包含要远程执行的方法的名称.另一种选择可以是:

Where "control" contains the name of the method to be executed remotely. The other alternative can be:

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

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

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

What would be the best approach? Or at least what are the trade-offs of using one approach instead of the other?

推荐答案

不要那样做.有消息:

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).

That way you send only the InputParameters message. The method to call is dictated by whether InputParameters.req contains an InputParametersA (implies that method A should be called), or InputParmetersB (for method B).

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

This avoids parsing a string to determine a method name (highly error prone), and instead gives you an enumeration to switch on (the possible content of the req field). Depending on the implementation of GPB you're using (C++, etc) you may even get a compile time warning if your switch statement doesn't adequately cover all values of that enumeration.

这也意味着确定哪些字段应该传递给方法没有问题;您将 InputParameters.req.a 传递到方法 A 或 .b 传递到方法 B.无需将它们分解为方法的单独参数,只需将整个内容作为单个参数传递即可.

It also means that there's no problems in determining which of the fields should be passed to a method; you're passing either InputParameters.req.a into method A or .b into method B. There's no need to break them out into separate parameters for a method, simple pass the whole thing in as a single parameter.

你可以用同样的方式定义不同的返回类型,通过一个 oneof 将它们全部传回.

You can define different return types in the same way, passing them all back through a single oneof.

替代方案

现在,如果您使用 ASN.1(在概念上与 GPB 相同),您可以对消息字段的值和/或大小设置约束(请参阅 这里,本 PDF 第 13 章.那样你自动执行参数验证,仅在 ASN.1 架构中定义.GPB 中缺少值/大小限制是一个明显的遗漏.

Now if you were using ASN.1 (which is conceptually the same kind of thing as GPB), you could set constraints on the values and / or sizes of message fields (see here, Chapter 13 in this PDF. That way you'd have parameter validation being performed automatically, defined solely in the ASN.1 schema. The lack of value / size constraints in GPB is a glaring omission.

看看这里(概述)这里(看起来不错的 C/C++ 的免费模式编译器),以及 此处(PDF,参考手册).

ASN.1 在其有线格式中具有更强的输入(如果您使用 BER 编码).可以查询有线比特流以找出它包含的消息类型.因此,无需像使用 GPB 那样将所有可能的消息包装到一个 oneof 中.

ASN.1 has stronger typing in its wire format (if you use BER encoding). It's possible to interrogate a wire bit stream to find out what type of message it contains. Thus there is no need to resort to wrapping all your possible messages up into a single oneof like you do with GPB.

这篇关于在 ZeroMQ 中使用 Protocol Buffers 实现 RPC的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆