从协议缓冲区过滤项目

时间:2013-08-12 16:33:12

标签: c++ protocol-buffers

我正在开发一种系统控制软件,用于处理硬件设备的控制和状态信息。为简单起见,我使用一个中等复杂的协议缓冲区结构来在线程之间进行通信。我还在网络接口上使用相同的结构,以便外部客户端可以控制和监视系统的所有部分。

该软件可能使用低比特率数据链路运行,因此我正在寻找减少网络负载的方法。因此我的问题是:

如果没有为每个I / O操作解析整个protobuf结构,有没有办法过滤(修剪)protobuf以在运行时删除某些消息?

例如,如果我有.proto

message Status {
    optional BusyMsg busy = 10;
    optional FaultMsg system_fault = 11;
    optional VoltageMsg rail_volts = 3000;

    optional InternalStatus internal = 4000;
}

message InternalStatus {
    optional PressureMsg head_pressure = 1;
    optional TempMgs cabinet_temp = 2;
}

是否有一种简单的方法可以删除(或禁止传输)rail_voltsinternal,可能是通过测试大型ID号(在这种情况下为3000和4000)?或者是否可以很好地使用可以提供帮助的扩展和属性?

我知道我可以在I / O边界调用我不想序列化的所有字段的Clear()。但我宁愿在.proto中标记它们,而不是依赖网络接口上的C ++代码来保持更新。 (到目前为止,internal子部分是我最好的想法。我可以剪掉一切。)

我不是在寻找一种通过结构研究的解决方案。我想知道我是否缺少API的优雅功能。

1 个答案:

答案 0 :(得分:0)

您可以定义缩小的状态消息,将完整的消息打印到字符串,然后将其解析为缩减消息。这意味着您只需要更改proto文件而不必担心C ++ API。 (复制在这里不是很漂亮。我还不知道如何分享这些原型。)

// foo.proto
syntax = "proto2";

message Status1 {
    optional int64 f1 = 1;
    optional int64 f2 = 2;
    optional int64 f3 = 3;
}

message Status2 {
    optional int64 f1 = 1;
    optional int64 f2 = 2;
}


// foo.cc
#include <iostream>
#include "experimental/seanmcl/proto/foo.pb.h"

int main(int argc, char* argv[]){

  string str;

  {
    Status1 s1;

    s1.set_f1(5);
    s1.set_f2(6);
    s1.set_f3(7);

    s1.SerializeToString(&str);
  }

  {
    Status2 s2;
    s2.ParseFromString(str);

    assert(s2.f1() == 5);
    assert(s2.f2() == 6);
  }

  return 0;
}

关于复制(虽然不是简单的消息),这有点好:

message Status {
    optional StatusRequired status_required = 1;
    optional int64 f3 = 3;
}

message StatusRequired {
    optional int64 f1 = 1;
    optional int64 f2 = 2;
}



{
  Status s3;
  StatusRequired* s4 = s3.mutable_status_required();

  s4->set_f1(5);
  s4->set_f2(6);
  s3.set_f3(7);

  s3.SerializeToString(&str);
}

{
  Status s3;
  s3.ParseFromString(str);
  StatusRequired* s4 (s3.mutable_status_required());

  cout << (s4->f1() == 5) << endl;;
  cout << (s4->f2() == 6) << endl;;
}

我现在认识到的是你的解决方案,字段的相对重要性被翻转了!