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;
    }
    }
  • 相关阅读:
    Linkerd 2.10(Step by Step)—将 GitOps 与 Linkerd 和 Argo CD 结合使用
    Linkerd 2.10(Step by Step)—多集群通信
    Linkerd 2.10(Step by Step)—使用 Kustomize 自定义 Linkerd 的配置
    Linkerd 2.10(Step by Step)—控制平面调试端点
    Linkerd 2.10(Step by Step)—配置超时
    Linkerd 2.10(Step by Step)—配置重试
    Linkerd 2.10(Step by Step)—配置代理并发
    本地正常运行,线上环境诡异异常原因集合
    Need to invoke method 'xxx' declared on target class 'yyy', but not found in any interface(s) of the exposed proxy type
    alpine 安装常用命令
  • 原文地址:https://www.cnblogs.com/zhangnianyong/p/9114209.html
Copyright © 2011-2022 走看看