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;
    }
    }
  • 相关阅读:
    linux g++编译dxf文件C++解析库dxflib
    linux g++使用总结
    一个使用three.js的网页DXF文件查看器dxf viewer
    node.js教程基础:node.js访问操作系统
    node.js教程基础:node.js全局对象
    node.js教程基础:node.js命令行选项
    node.js教程基础:node.js包管理器
    node.js教程基础:node.js REPL
    node.js教程基础:第一个node.js程序
    node.js教程基础:node.js安装
  • 原文地址:https://www.cnblogs.com/zhangnianyong/p/9114209.html
Copyright © 2011-2022 走看看