rec*_*ion 5 c++ protocol-buffers
我有一个C ++程序,可以将各种事件(例如StatusEvent,DetectionEvent具有不同的原型消息定义)发送到消息服务(当前为Active MQ,通过activemq-cpp APU)。我想编写一个消息侦听器,以接收这些消息,解析它们并将它们写入cout,以进行调试。侦听器具有status_event_pb.h和detection_event_pb.h链接。
我的问题是:如何在不知道事件类型的情况下解析它?我想做类似的事情(用伪代码)
receive event
type = parseEventType(event);
if( type == events::StatusEventType) {
events::StatusEvent se = parseEvent(event);
// do stuff with se
}
else {
// handle the case when the event is a DetectionEvent
}
Run Code Online (Sandbox Code Playgroud)
我看了这个问题,但是不确定扩展是否是正确的选择。简短的代码片段将为您提供帮助。关于protobuf的例子非常罕见!
谢谢!
似乎扩展确实是可行的方法,但是我还有最后一点要解决。这是我到目前为止的原型定义:
// A general event, can be thought as base Event class for other event types.
message Event {
required int64 task_id = 1;
required string module_name = 2; // module that sent the event
extensions 100 to 199; // for different event types
}
// Extend the base Event with additional types of events.
extend Event {
optional StatusEvent statusEvent = 100;
optional DetectionEvent detectionEvent = 101;
}
// Contains one bounding box detected in a video frame,
// representing a region of interest.
message DetectionEvent {
optional int64 frame = 2;
optional int64 time = 4;
optional string label = 6;
}
// Indicate status change of current module to other modules in same service.
// In addition, parameter information that is to be used to other modules can
// be passed, e.g. the video frame dimensions.
message StatusEvent {
enum EventType {
MODULE_START = 1;
MODULE_END = 2;
MODULE_FATAL = 3;
}
required EventType type = 1;
required string module_name = 2; // module that sent the event
// Optional key-value pairs for data to be passed on.
message Data {
required string key = 1;
required string value = 2;
}
repeated Data data = 3;
}
Run Code Online (Sandbox Code Playgroud)
我现在的问题是(1)如何知道Event消息包含哪个特定事件,以及(2)确保它仅包含一个此类事件(根据定义,它可以同时包含a StatusEvent和a DetectionEvent)。
我不会为此使用协议缓冲区,但这可能是很少使用和其他习惯的结合。
不管怎样,我想我会在这里使用一个抽象类,以简化一般处理并包含路由信息。不会使用 protobuf 定义的类,并且包含 protobuf 消息。
class Message
{
public:
Type const& GetType() const;
Origin const& GetOrigin() const;
Destination const& GetDestination() const;
// ... other informations
template <class T>
void GetContent(T& proto) const
{
proto.ParseFromIstream(&mContent); // perhaps a try/catch ?
}
private:
// ...
std::stringstream mContent;
};
Run Code Online (Sandbox Code Playgroud)
通过这种结构,您可以轻松地进行一般和特定的处理:
void receive(Message const& message)
{
LOG("receive - " << message.GetType() << " from " << message.GetOrigin()
<< " to " << message.GetDestination());
if (message.GetType() == "StatusEvent")
{
StatusEvent statusEvent;
message.Decode(statusEvent);
// do something
}
else if (message.GetType() == "DetectionEvent")
{
DetectionEvent detectionEvent;
message.Decode(detectionEvent);
// do something
}
else
{
LOG("receive - Unhandled type");
}
}
Run Code Online (Sandbox Code Playgroud)
std::unordered_map<Type,Handler>当然,如果您使用 a而不是硬编码链,那会更漂亮if / else if + / else,但原理仍然相同: