Ed Johns
Ed Johns

Reputation: 211

websocketpp callback (Class method via function pointer)

I took the example https://github.com/zaphoyd/websocketpp/blob/develop/examples/testee_server/testee_server.cpp and created a simple class as follows:

namespace __webauth__ {

struct ws_config: public websocketpp::config::asio {
    // pull default settings from our core config
    typedef websocketpp::config::asio core;

    typedef core::concurrency_type concurrency_type;
    typedef core::request_type request_type;
    typedef core::response_type response_type;
    typedef core::message_type message_type;
    typedef core::con_msg_manager_type con_msg_manager_type;
    typedef core::endpoint_msg_manager_type endpoint_msg_manager_type;

    typedef core::alog_type alog_type;
    typedef core::elog_type elog_type;
    typedef core::rng_type rng_type;
    typedef core::endpoint_base endpoint_base;

    static bool const enable_multithreading = true;

    struct transport_config: public core::transport_config {
        typedef core::concurrency_type concurrency_type;
        typedef core::elog_type elog_type;
        typedef core::alog_type alog_type;
        typedef core::request_type request_type;
        typedef core::response_type response_type;

        static bool const enable_multithreading = true;
    };

    typedef websocketpp::transport::asio::endpoint<transport_config> transport_type;

    static const websocketpp::log::level elog_level =
            websocketpp::log::elevel::none;
    static const websocketpp::log::level alog_level =
            websocketpp::log::alevel::none;

    /// permessage_compress extension
    struct permessage_deflate_config {
    };

    typedef websocketpp::extensions::permessage_deflate::enabled<
            permessage_deflate_config> permessage_deflate_type;
};

typedef websocketpp::server<ws_config> server;

// use placeholders
using websocketpp::lib::placeholders::_1;
using websocketpp::lib::placeholders::_2;
using websocketpp::lib::bind;

// define message type
typedef server::message_ptr message_ptr;

// define property tree (JSON)
using boost::property_tree::ptree;
using boost::property_tree::basic_ptree;

class Dispatcher {
public:
    void start();

private:
    server dispatcher;       // Create a server endpoint
    short dport = 8888;

    // callbacks
    void on_message(server* s, websocketpp::connection_hdl hdl, message_ptr msg);
};

} // end webauth namespace

But when I try to call the on_message callback from the start() member function, as follows:

dispatcher.set_message_handler(bind(&on_message,&dispatcher,::_1,::_2))

I get the following error:

Multiple markers at this line
    - required from here
    - ISO C++ forbids taking the address of an unqualified or parenthesized non-static member function to form a pointer to 
     member function. Say ‘&__webauth__::Dispatcher::on_message’ [-fpermissive]
    - candidate is:
    - no matching function for call to 
     ‘websocketpp::server<__webauth__::ws_config>::set_message_handler(boost::_bi::bind_t<boost::_bi::unspecified, void 
     (__webauth__::Dispatcher::*)(websocketpp::server<__webauth__::ws_config>*, std::weak_ptr<void>, 
     std::shared_ptr<websocketpp::message_buffer::message<websocketpp::message_buffer::alloc::con_msg_manager> >), 
     boost::_bi::list3<boost::_bi::value<websocketpp::server<__webauth__::ws_config>*>, boost::arg<1>, boost::arg<2> > >)’

I understand that I need to properly call the class methods via a function pointer but I don't know how to make this call for the on_message callback within the class that I created. Does anyone know how to accomplish this task?

Here is the start() function:

// ********************
//  Dispatcher (Public)
// ********************

void Dispatcher::start() {
    info("Dispatcher::start");

    try {
        // Total silence
        dispatcher.clear_access_channels(websocketpp::log::alevel::all);
        dispatcher.clear_error_channels(websocketpp::log::alevel::all);

        // Initialize ASIO
        dispatcher.init_asio();
        dispatcher.set_reuse_addr(true);

        // Register our message handler
       dispatcher.set_message_handler(bind(&on_message,&dispatcher,::_1,::_2));

        // Listen on specified port with extended listen backlog
        dispatcher.set_listen_backlog(8192);
        dispatcher.listen(dport);

        // Start the dispatcher accept loop
        dispatcher.start_accept();

        typedef websocketpp::lib::shared_ptr<websocketpp::lib::thread> thread_ptr;
        thread_ptr ts;
        ts = websocketpp::lib::make_shared<websocketpp::lib::thread>(&server::run, &dispatcher);
        ts->join();

    } catch (websocketpp::exception const & e) {
        std::cout << "exception: " << e.what() << std::endl;
    }
}

Upvotes: 1

Views: 871

Answers (1)

Ed Johns
Ed Johns

Reputation: 211

The problem with the callback was resolved by passing the Class Method function pointer and object (this) properly:

dispatcher.set_message_handler(bind(&Dispatcher::on_message,this,&dispatcher,::_1,::_2));

You need to pass the Class Method function pointer (&Dispatcher::on_message) and the object (this) properly.

Upvotes: 1

Related Questions