正在从协议缓冲区筛选项目

Filtering items from a protocol buffer

本文关键字:筛选 项目 缓冲区 协议      更新时间:2023-10-16

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

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

在不为每个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的一个优雅功能。

您可以定义一个简化的状态消息,将完整的状态消息打印为字符串,并将其解析为简化的消息。这意味着您只需要更改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;;
}

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