• websocketpp的回调函数解析


    说明

    这个项目使用很简单,但是里面用了很多语法糖,c++11的特性,懵逼了两天才慢慢搞明白。
    原谅我,手生了。
    当你了解 bind、占位符、auto、lambda表达式、函数指针、函数对象也就不用看这里了。

    websocketpp项目
    部分代码

    #include 
    #include 
    typedef websocketpp::server<websocketpp::config::asio> server;
    
    using websocketpp::lib::placeholders::_1;
    using websocketpp::lib::placeholders::_2;
    using websocketpp::lib::bind;
    
    // pull out the type of messages sent by our config
    typedef server::message_ptr message_ptr;
    
    void on_message(server* s,websocketpp::connection_hdl, server::message_ptr);
    void on_open(websocketpp::connection_hdl hdl);
    void on_close(websocketpp::connection_hdl hdl);
        server echo_server;
    
    echo_server.set_message_handler(bind(&on_message,&echo_server,::_1,::_2));
    echo_server.set_open_handler(bind(&on_open,::_1));
    echo_server.set_close_handler(bind(&on_close,::_1));
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    里面的回调函数

    // Define a callback to handle incoming messages
    void on_message(server* s, websocketpp::connection_hdl hdl, message_ptr msg) {
        std::cout << "robin:on_message called with hdl: " << hdl.lock().get()
                  << " and message: " << msg->get_payload()
                  << std::endl;
    
        // check for a special command to instruct the server to stop listening so
        // it can be cleanly exited.
        if (msg->get_payload() == "stop-listening") {
            s->stop_listening();
            return;
        }
    
        try {
            s->send(hdl, msg->get_payload(), msg->get_opcode());
        } catch (websocketpp::exception const & e) {
            std::cout << "Echo failed because: "
                      << "(" << e.what() << ")" << std::endl;
        }
    }
    
    void on_open(websocketpp::connection_hdl hdl) {
        std::cout << "Controller connected." << std::endl;
    }
    
    void on_close(websocketpp::connection_hdl hdl) {
        std::cout << "Controller disconnected." << std::endl<<std::endl;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    open_handler的回溯

    现在一般都直接用函数指针了,而是来了个绑定

    	//例如
        void set_open_handler(open_handler h) {
            m_alog->write(log::alevel::devel,"set_open_handler");
            scoped_lock_type guard(m_mutex);
            m_open_handler = h;
        }
         继续往下跟踪
        open_handler                m_open_handler;
    	 继续往下跟踪
    	typedef lib::function<void(connection_hdl)> open_handler;
    	/// 继续往下跟踪
    	typedef lib::weak_ptr<void> connection_hdl;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    里面的 void(connection_hdl) 是一个函数指针,它的参数是一个只能指针。可以理解为 void(void *),其实这就是根上的函数指针。
    因为设置回调函数,使用了 lib::function形式,所以传入的参数要用 std::bind 进行处理。
    也就是

    echo_server.set_open_handler(bind(&on_open,::_1));
    
    • 1

    message_handler的 回溯

    void set_message_handler(message_handler h) {
        m_alog->write(log::alevel::devel,"set_message_handler");
        scoped_lock_type guard(m_mutex);
        m_message_handler = h;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    我一直奇怪

    void on_message(server* s,websocketpp::connection_hdl, server::message_ptr);
    
    • 1

    为什么这么定义。
    跟踪下去

    typedef typename connection_type::message_handler message_handler;  
    
    • 1

    找到这里,ide就往下跳不动了。

    	///再往下
        /// Type of the connections that this endpoint creates
        typedef connection connection_type;
    
    	/// 再往下
    	template <typename connection, typename config>
    	class endpoint : public config::transport_type, public config::endpoint_base {
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    后来在 asr\include\websocketpp\connection.hpp中找到了

        // Message handler (needs to know message type)
        typedef lib::function<void(connection_hdl,message_ptr)> message_handler;
    
    • 1
    • 2

    至此结束。

  • 相关阅读:
    分布式数据库选型之争:数据库向左,中间件向右
    Android-Handler源码解析-Looper
    307. Range Sum Query - Mutable
    OpenCV Python – 使用SIFT算法实现两张图片的特征匹配
    【Computer Vision】基于ResNet-50实现CIFAR10数据集分类
    Hi3861 OpenHarmony嵌入式应用入门--点灯
    Git 常用命令总结
    Springboot 整合 Java DL4J 实现智能客服
    【Python机器学习】零基础掌握OPTICS聚类
    一文了解循环神经网络
  • 原文地址:https://blog.csdn.net/lanxiaziyi/article/details/127846602