0

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

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

如果不为每个 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 的一个优雅特性。

4

1 回答 1

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;;
}

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

于 2013-08-12T17:19:42.083 回答