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;
???}
}
Qt写websocketpp服务端
原文地址:https://www.cnblogs.com/zhangnianyong/p/9114209.html