通用消息调度库

generic message dispatching library?

本文关键字:调度 消息      更新时间:2023-10-16

是否有标准的方法来消除读循环中的switch/case块?

enum msg_type
{
    message_type_1,
    //msg types
}
struct header
{
    msg_type _msg_type;
    uint64_t _length;
}
struct message1
{
    header _header;
    //fields
}
struct message2
{
    header _header;
    //fields
}
//socket read loop
void read(//blah)
{
    //suppose we have full message here
    char* buffer; //the buffer that holds data
    header* h = (header*)buffer;
    msg_type type = h->_msg_type;
    switch(type)
    {
    case msg_type_1:
        message1* msg1 = (message1*)buffer;
        //Call handler function for this type
    //rest
    }
}

这意味着我必须从处理程序容器基类继承,该基类的形式为:

class handler_container_base
{
public:
    virtual void handle(message1* msg){}
    virtual void handle(message2* msg){}
    //etc
}

并将该类型的对象传递到消息循环可以看到的位置,并要求他回拨这些对象。

一个问题是,即使我只想为一个类型实现和注册一个处理程序,我也必须从这个类继承。另一个是这看起来很难看。

我想知道是否有处理这个问题的现有库(应该是免费的)。或者没有比这样更好的方法了吗?

其他避免继承的方法有:

  1. 对于一组封闭类型:

    使用变体:

    variant<message1_t, message2_t> my_message;
    

    有访客,你可以做剩下的。我推荐boost.variant.

  2. 您还可以对一组打开的类型使用boost::any,并在运行时复制消息。不过,在某些情况下,您将不得不转换回原始类型。

  3. 另一个解决方案遵循Poco.DynamicAny的思路,它将尝试转换为赋值中左侧的类型,类似于动态语言。但是您需要自己为您的类型注册转换器。