Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. a router for websocket messages, is there anything wrong with this implementation
Qt 6.11 is out! See what's new in the release blog

a router for websocket messages, is there anything wrong with this implementation

Scheduled Pinned Locked Moved Unsolved General and Desktop
1 Posts 1 Posters 420 Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • S Offline
    S Offline
    sadeq
    wrote on last edited by sadeq
    #1

    I've built a router that is similar in syntax to laravel's router
    I know "get" and "post" will sound just like http, but I'm using them for convenience.
    here is the implementation:
    router.h

    #ifndef ROUTER_H
    #define ROUTER_H
    
    #include "message.h"
    class CNTRLR{}; //MSVC will throw C2440 when using reinterpret_cast with undefined classes
    
    using MemberCallback = void (CNTRLR::*)(Message &);
    
    struct MemberCallbackInfo
    {
        CNTRLR *instance;
        MemberCallback ptr;
    };
    
    typedef QMap<QString,MemberCallbackInfo> MemberCallbacks;
    
    class Router
    {
    public:
        explicit Router();
        void route(Message &message);
    
        template <class T> static void registerRoute(MemberCallbacks *callBacks,
        const QString& action,
        T *instance, void (T::*ptr)(Message &)){MemberCallbackInfo obj={reinterpret_cast<CNTRLR *>(instance),
        reinterpret_cast<MemberCallback>(ptr)};
        callBacks->insert(action, obj);}
        template <class T> static void get   (const QString& action, T *instance, void (T::*ptr)(Message &)){registerRoute(&getRoutes,action,instance,ptr);}
        template <class T> static void post  (const QString& action, T *instance, void (T::*ptr)(Message &)){registerRoute(&postRoutes,action,instance,ptr);}
    
    private:
        static MemberCallbacks getRoutes;
        static MemberCallbacks postRoutes;
    
    };
    
    typedef Router Route;
    
    #endif // ROUTER_H
    

    router.cpp

    #include "router.h"
    MemberCallbacks Router::getRoutes;
    MemberCallbacks Router::postRoutes;
    Router::Router()
    {
    
    }
    
    void Router::route(Message &message)
    {
        if(message.method()=="GET")
        {
            MemberCallbackInfo cb= getRoutes.value(message.action());
            (cb.instance->*cb.ptr)(message);
        }
        else if(message.method()=="POST")
        {
            MemberCallbackInfo cb= postRoutes.value(message.action());
            (cb.instance->*cb.ptr)(message);
        }
    }
    

    now if I want to route something I just have to type something like this from anywhere I want in the app

    Route::post("user/auth", this, &AuthController::authenticate);
    

    I've used a tricky way to store member function pointers and I'm not sure if it's type safe
    I used template functions so that I can make sure that the instance and the member function pointer are of the same class,
    I'm storing the info in a struct called "MemberCallbackInfo".

    class CNTRLR is just a dummy class.

    according to the Standard (section 5.2.10/9), you can use reinterpret_cast to store a member function for one class inside a member function pointer for an unrelated class,
    and that is what I did with the dummy class.

    is there a more elegant way(like utilizing Qt's signals,slots and Qt's metaobject system) to implement such router while keeping the same routing syntax above ?

    1 Reply Last reply
    0

    • Login

    • Login or register to search.
    • First post
      Last post
    0
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    • Get Qt Extensions
    • Unsolved