Qt寫websocketpp服務端

一、下載websocketpp,地址爲https://github.com/zaphoyd/websocketpp,版本爲0.7。ios

二、下載boost,地址爲https://www.boost.org/,版本爲1.6.3。git

三、說明:websocketpp並非必須須要boost,若是C++編譯爲C11以上,是能夠不用的。github

四、Qt建立一個console工程(如:websocketServer),將下載下來的websocket_master裏面的websocket文件夾放到該工程目錄下,在webSocketServer.pro文件中添加include(websocket/websocket.pri),web

五、建立websocket_server類,頭文件websocket_server.h內容以下:websocket

#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;
};

六、websocket_server.cpp內容以下:      socket

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;    }}
相關文章
相關標籤/搜索