我有一个发送各种事件的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
}
我看了this question,但我不确定延伸是否是正确的方式。我们非常感谢一个简短的代码片段。关于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;
}
我现在的问题是(1)如何知道事件消息包含哪个特定事件,以及(2)确保它只包含一个这样的事件(根据定义,它可以包含StatusEvent
和DetectionEvent
)。
答案 0 :(得分:3)
我不会使用Protocol Buffers,但这可能是很少使用和其他习惯的组合。
无论如何,我想我会在这里使用一个抽象类来简化一般处理并包含路由信息。不使用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;
};
使用这种结构,您可以在手指尖处进行一般处理和特定处理:
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");
}
}
当然,如果您使用std::unordered_map<Type,Handler>
而不是硬编码的if / else if + / else
链,它会更漂亮,但原则仍然相同: