【问题标题】:Send protocol buffer data via Socket and determine the class通过 Socket 发送协议缓冲区数据并确定类
【发布时间】:2014-07-03 20:31:59
【问题描述】:

我现在正在研究 Google 的协议缓冲区并有一个问题。如果我有多个 .proto 文件,因此有多个类,当数据通过套接字发送以确定它是哪种类型时,是否有可能?

例如我有两个类,我们称它们为 person.proto 和 adress.proto。现在我通过网络发送其中一个。接收者如何判断是人还是地址?

我正在用 C++ 做这个。

我的尝试是在消息周围添加一个框架,包含长度和类型。但我想知道类型的东西是否已经有某种实现,所以我不重新实现现有的东西。

【问题讨论】:

    标签: c++ sockets protocol-buffers


    【解决方案1】:

    是的,这是可能的。 Protobuf 支持使用所谓的message descriptors 进行反射。

    但是(如另一个答案中所述)您需要一个可靠的众所周知的根消息类型。与其引入自己的消息识别机制,恕我直言,最好使用protobufs extension mechanism

    这是我们在生产中的示例

    package Common.ConfigurationCommands;
    
    message UcpConfiguration
    {
         optional uint32 componentIndex = 1;
         optional ConfigCmdStatus configCmdResponseStatus = 2;
         optional string configErrorDescription = 3;
    
         extensions 100 to max;
    }
    

    扩展看起来像

    import "Common/ConfigurationCommands.proto";
    
    message AmplifierConfiguration
    {
        extend Common.ConfigurationCommands.UcpConfiguration 
        {
            optional AmplifierConfiguration amplifierConfiguration = 108;
        }
        optional uint32 preemphasis = 1;
    }
    

    import "Common/ConfigurationCommands.proto";
    
    message FrontendConfiguration
    {
        extend Common.ConfigurationCommands.UcpConfiguration 
        {
            optional FrontendConfiguration frontendConfiguration = 100;
        }
        optional bool frontendActive = 1;
        optional uint32 refInputComponentIndex = 2;
    
        extensions 100 to max;
    }
    

    您可以查看this part of the documentation,了解如何处理您的 C++ 代码中的扩展。

    【讨论】:

    • 这正是我一直在寻找的。谢谢!
    【解决方案2】:

    无法检测到哪个对象被序列化,Protobuf 不这样做。但是你可以很容易地使用 protobuf 来处理它:

    1) 方法:只发送具有类型和字符串正文的消息。在正文中,您将序列化您的对象,在类型中您将显示哪个对象被序列化:

    类似的东西:

    package MyGreatPackage;
    
    message Pack
    {
        required bytes packcode = 1;
        //code for data/query
        required bytes  mess = 2;
    }
    
    message Data
    {
    //anything you need to
    }
    
    message Query
    {
    //anything you need to
    }
    

    因此,您将始终发送消息包,其中将定义“混乱”字段中的确切对象。

    2) 方法: protobuf 允许这种技术在没有包装器的情况下实现相同的效果,请看这里:https://developers.google.com/protocol-buffers/docs/techniques?hl=ru#union

    message OneMessage {
      enum Type { FOO = 1; BAR = 2; BAZ = 3; }
    
      // Identifies which field is filled in.
      required Type type = 1;
    
      // One of the following will be filled in.
      optional Foo foo = 2;
      optional Bar bar = 3;
      optional Baz baz = 4;
    }
    

    因此,您可以将所有可能发送的类设置为可选,并通过所需参数确定它们的类型。

    不过,对我来说,第一个 varians 似乎更好,选择你喜欢的。

    【讨论】:

    • '无法检测到哪个对象被序列化了,Protobuf 不这样做。' 注意有这个dynamic message mechanism,但你需要那些描述符我提到。
    • 谢谢,这是第三种方法,我不知道:-)
    猜你喜欢
    • 1970-01-01
    • 2015-10-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多