zoukankan      html  css  js  c++  java
  • Qt写websocketpp服务端

    1、下载websocketpp,地址为https://github.com/zaphoyd/websocketpp,版本为0.7。

    2、下载boost,地址为https://www.boost.org/,版本为1.6.3。

    3、说明:websocketpp并不是必须需要boost,如果C++编译为C11以上,是可以不用的。

    4、Qt创建一个console工程(如:websocketServer),将下载下来的websocket_master里面的websocket文件夹放到该工程目录下,在webSocketServer.pro文件中添加include(websocket/websocket.pri),

    5、创建websocket_server类,头文件websocket_server.h内容如下:

    #include <websocketpp/config/asio_no_tls.hpp>
    #include <websocketpp/server.hpp>
    
    
    #include <websocketpp/impl/connection_impl.hpp>
    #include <websocketpp/config/core.hpp>
    #include <websocketpp/connection.hpp>
    #include <websocketpp/endpoint.hpp>
    #include <websocketpp/close.hpp>
    #include <websocketpp/uri.hpp>
    
    
    #include <map>
    #include <string>
    #include <sstream>
    #include <cstdlib>
    #include <iostream>
    #include <QDateTime>
    
    
    using websocketpp::lib::placeholders::_1;
    using websocketpp::lib::placeholders::_2;
    using websocketpp::lib::bind;
    using websocketpp::endpoint;
    using websocketpp::connection;
    
    
    typedef websocketpp::server<websocketpp::config::asio> server;
    typedef server::message_ptr message_ptr;
    /////////////////////////////////////////////////////////////////////
    class connection_metadata
    {
    public:
    typedef websocketpp::lib::shared_ptr<connection_metadata> ptr;
    connection_metadata(websocketpp::connection_hdl hdl,std::string strRemote) :
    m_hdl(hdl),strRemote(strRemote)
    {}
    
    
        void setDateTime()
    {
    dt = QDateTime::currentDateTime();
    }
        QDateTime getDateTime() const
    {
    return dt;
    }
        void sethdl(websocketpp::connection_hdl hdl)
    {
    m_hdl = hdl;
    }
        websocketpp::connection_hdl gethdl()
    {
    return m_hdl;
    }
        void update_time()
    {
    dt = QDateTime::currentDateTime();
    }
        void setRemote(std::string strRemote)
    {
    this->strRemote = strRemote;
    }

    std::string getRemote() const
    {
    return strRemote;
    }
    private:
    QDateTime dt;
    std::string strRemote;
    websocketpp::connection_hdl m_hdl;
    };
    /////////////////////////////////////////////////////////////////////
    class websocket_server
    {
    public:
    websocket_server();
    ~websocket_server();

    static void on_open(server* s,websocket_server* pWebSocket,websocketpp::connection_hdl hdl);
    static void on_close(server* s,websocket_server* pWebSocket,websocketpp::connection_hdl hdl);
    static void on_message(server* s,websocket_server* pWebSocket,websocketpp::connection_hdl hdl,message_ptr msg);
        void start(int port);
    private:
    typedef std::map<std::string,connection_metadata::ptr> con_list;

    server echo_server;
    con_list m_connection_list;
        websocketpp::lib::shared_ptr<websocketpp::lib::thread> m_thread;
    };

    6、websocket_server.cpp内容如下:      

    websocket_server::websocket_server()
    {
    m_connection_list.clear();
    }
    websocket_server::~websocket_server()
    {
    for(con_list::iterator iter = m_connection_list.begin();iter != m_connection_list.end();)
    {
    echo_server.close(iter->second->gethdl(),websocketpp::close::status::going_away,"");
    m_connection_list.erase(iter++);
    }
        echo_server.stop_perpetual();
    m_thread->join();
    }
    //连接
    void websocket_server::on_open(server *s,websocket_server* pWebSocket,websocketpp::connection_hdl hdl)
    {
    server::connection_ptr con = s->get_con_from_hdl(hdl);
    const std::string strRemote = con->get_remote_endpoint();
    con_list::iterator iter = pWebSocket->m_connection_list.find(strRemote);
        if(iter == pWebSocket->m_connection_list.end())
    {
    connection_metadata* pmetadata = new connection_metadata(hdl,strRemote);
    pWebSocket->m_connection_list.insert(make_pair(strRemote,pmetadata));
    }
    else
    {
    iter->second->sethdl(hdl);
    }
    }
    //断开
    void websocket_server::on_close(server* s,websocket_server* pWebSocket,websocketpp::connection_hdl hdl)
    {
    server::connection_ptr con = s->get_con_from_hdl(hdl);
    const std::string strRemote = con->get_remote_endpoint();
    con_list::iterator iter = pWebSocket->m_connection_list.find(strRemote);
        if(iter != pWebSocket->m_connection_list.end())
    {
    pWebSocket->m_connection_list.erase(iter);
    }
    }
    //通信
    void websocket_server::on_message(server* s,websocket_server* pWebSocket,websocketpp::connection_hdl hdl, message_ptr msg)
    {
    if(msg->get_opcode() == websocketpp::frame::opcode::text)
    {
    server::connection_ptr con = s->get_con_from_hdl(hdl);
    const std::string strRemote = con->get_remote_endpoint();
         std::cout << strRemote <<std::endl;
    }
        std::cout << "on_message called with hdl: " << hdl.lock().get() << " and message: " << msg->get_payload() << std::endl;

    if(msg->get_payload() == "stop-listening")
    {
    s->stop_listening();
    return;
    }

    try
    {
    s->send(hdl, msg->get_payload(),msg->get_opcode());//接收到的数据原路返回
    }
        catch (const websocketpp::lib::error_code& e)
    {
    std::cout << "Echo failed because: " << e << "(" << e.message() << ")" << std::endl;
    }
    }
    void websocket_server::start(int port)
    {
    try
    {
    // Set logging settings
    echo_server.set_access_channels(websocketpp::log::alevel::all);
    echo_server.clear_access_channels(websocketpp::log::alevel::frame_payload);
            // Initialize Asio
    echo_server.init_asio();
    echo_server.start_perpetual();
            echo_server.set_open_handler(bind(&on_open,&echo_server,this,::_1));
    echo_server.set_close_handler(bind(&on_close,&echo_server,this,::_1));
    echo_server.set_message_handler(bind(&on_message,&echo_server,this,::_1,::_2));
            // Listen on port 9002
    echo_server.listen(port);
            // Start the server accept loop
    echo_server.start_accept();
            // Start the ASIO io_service run loop
    //echo_server.run();
    m_thread = websocketpp::lib::make_shared<websocketpp::lib::thread>(&server::run,&echo_server);//用线程m_thread的run函数来跑echo_server的run,这样可以避免程序卡在echo_server的run里
    }
    catch (websocketpp::exception const & e)
    {
    std::cout << e.what() << std::endl;
    }
    catch (...)
    {
    std::cout << "other exception" << std::endl;
    }
    }
  • 相关阅读:
    jchdl
    jchdl
    UVa 10256 (判断两个凸包相离) The Great Divide
    UVa 11168 (凸包+点到直线距离) Airport
    LA 2572 (求可见圆盘的数量) Kanazawa
    UVa 10652 (简单凸包) Board Wrapping
    UVa 12304 (6个二维几何问题合集) 2D Geometry 110 in 1!
    UVa 10674 (求两圆公切线) Tangents
    UVa 11796 Dog Distance
    LA 3263 (平面图的欧拉定理) That Nice Euler Circuit
  • 原文地址:https://www.cnblogs.com/zhangnianyong/p/9114209.html
Copyright © 2011-2022 走看看