一、客户端代码
客户端代码-头文件
#ifndef Z__WEBSOCKET____m_client_H__
#define Z__WEBSOCKET____m_client_H__
#include <websocketpp/client.hpp>
#include <websocketpp/config/asio_no_tls.hpp>
#include <iostream>
#include <functional>
#include <algorithm>
using websocketpp::lib::placeholders::_1;
using websocketpp::lib::placeholders::_2;
// WebSocket++ 客户端配置
using websocket_client = websocketpp::client<websocketpp::config::asio>;
// 定义消息处理器类
class ZWebsocketClient {
public:
ZWebsocketClient();
// 连接成功回调函数
void on_open(websocketpp::connection_hdl hdl);
// 消息接收回调函数
void on_message(websocketpp::connection_hdl hdl, websocket_client::message_ptr msg);
// 连接关闭回调函数
void on_close(websocketpp::connection_hdl hdl);
// 运行 WebSocket 客户端
void run(const std::string& ip, const int port);
private:
// WebSocket 客户端对象
websocket_client m_client;
};
#endif // ! Z__WEBSOCKET____m_client_H__
客户端代码-实现
#include "WebSocketClient.h"
ZWebsocketClient::ZWebsocketClient()
{
// 设置连接成功回调函数
m_client.set_open_handler(std::bind(&ZWebsocketClient::on_open, this, ::_1));
// 设置消息接收回调函数
m_client.set_message_handler(std::bind(&ZWebsocketClient::on_message, this, ::_1, ::_2));
// 设置连接关闭回调函数
m_client.set_close_handler(std::bind(&ZWebsocketClient::on_close, this, ::_1));
}
// 连接成功回调函数
void ZWebsocketClient::on_open(websocketpp::connection_hdl hdl)
{
std::cout << "Connected to the server." << std::endl;
// 发送消息
m_client.send(hdl, "Hello, server!", websocketpp::frame::opcode::text);
}
// 消息接收回调函数
void ZWebsocketClient::on_message(websocketpp::connection_hdl hdl, websocket_client::message_ptr msg)
{
//打印消息
std::cout << "Received message: " << msg->get_payload() << std::endl;
//关闭连接
m_client.close(hdl, websocketpp::close::status::going_away, "close connect");
}
// 连接关闭回调函数
void ZWebsocketClient::on_close(websocketpp::connection_hdl hdl)
{
}
// 运行 WebSocket 客户端
void ZWebsocketClient::run(const std::string &ip,const int port)
{
m_client.init_asio();
std::string url = "ws://" + ip + ":" + std::to_string(port);
// 创建连接
websocketpp::lib::error_code ec;
websocket_client::connection_ptr con = m_client.get_connection(url, ec);
if (ec) {
std::cout << "Error creating connection: " << ec.message() << std::endl;
return;
}
// 启动线程运行客户端
m_client.connect(con);
m_client.run();
}
二、服务器代码
服务器代码-头文件
#ifndef __WEBSOCKET__SERVER__H__
#define __WEBSOCKET__SERVER__H__
#include <websocketpp/config/asio_no_tls.hpp>
#include <websocketpp/server.hpp>
#include <boost/uuid/uuid.hpp>
#include <boost/uuid/uuid_io.hpp>
#include <boost/uuid/uuid_generators.hpp>
#include <boost/algorithm/string.hpp>
#include <map>
#include <mutex>
#include <string>
#include <iostream>
#include <vector>
#include <algorithm>
using websocket_server = websocketpp::server<websocketpp::config::asio>;
using websocket_connect_hdl = websocketpp::connection_hdl;
using websocketpp::lib::bind;
using websocketpp::lib::placeholders::_1;
using websocketpp::lib::placeholders::_2;
class ZWebsocketServer
{
public:
ZWebsocketServer();
~ZWebsocketServer();
void RunService(int);
public:
void on_message(websocket_server* s, websocketpp::connection_hdl hdl, websocket_server::message_ptr msg);
void on_open(websocket_server* s, websocketpp::connection_hdl hdl);
void on_close(websocket_server* s, websocketpp::connection_hdl hdl);
private:
std::mutex m_mutex;
websocket_server *m_server = nullptr;
std::map<std::string,websocket_connect_hdl>m_map;
};
#endif // !__WEBSOCKET__SERVER__H__
服务器代码-实现
#include "WebSocketServer.h"
void ZWebsocketServer::on_message(websocket_server* s, websocketpp::connection_hdl hdl, websocket_server::message_ptr msg)
{
std::string str = msg->get_payload(); //获取uuid
std::vector<std::string> in; //解析参数
boost::split(in, str, boost::is_any_of(":"));
if (in.size() >= 2)
{
//TODO:
}
else
{
}
}
void ZWebsocketServer::on_open(websocket_server* s, websocketpp::connection_hdl hdl)
{
std::unique_lock<std::mutex> lock(m_mutex);
boost::uuids::uuid uuid = boost::uuids::random_generator()();
std::string uuid_str = boost::uuids::to_string(uuid);
m_map.insert(std::make_pair(uuid_str, hdl)); //通过uuid进行记录
s->send(hdl, uuid_str, websocketpp::frame::opcode::text);
}
void ZWebsocketServer::on_close(websocket_server* s, websocketpp::connection_hdl hdl)
{
std::unique_lock<std::mutex> lock(m_mutex);
std::string key = "";
for (auto& x : m_map)
{
if (x.second.lock() == hdl.lock())
{
key = x.first;
break;
}
}
if (!key.empty())
{
m_map.erase(key);
}
}
void ZWebsocketServer::RunService(int port)
{
m_server = new websocket_server;
m_server->clear_access_channels(websocketpp::log::alevel::all);
m_server->init_asio();
m_server->set_message_handler(std::bind(&ZWebsocketServer::on_message, this, m_server, ::_1, ::_2));
m_server->set_open_handler(std::bind(&ZWebsocketServer::on_open, this, m_server, ::_1));
m_server->set_close_handler(std::bind(&ZWebsocketServer::on_close, this, m_server, ::_1));
m_server->listen(port);
std::cout << "Listen port ... " << port << std::endl;
m_server->start_accept();
m_server->run();
}
ZWebsocketServer::ZWebsocketServer()
{
}
ZWebsocketServer::~ZWebsocketServer()
{
if (m_server != nullptr)
{
delete m_server;
m_server = nullptr;
}
}
三、代码调用方法
#include <iostream>
#include <thread>
#include <functional>
#include "model/websocket/WebSocketServer.h"
#include "model/websocket/WebSocketClient.h"
#define __SERVER 0
int main(int argc, char* argv[])
{
#if __SERVER
ZWebsocketServer server;
std::thread th(std::bind(&ZWebsocketServer::RunService, &server, 9310));
th.join();
#else
ZWebsocketClient server;
std::thread th(std::bind(&ZWebsocketClient::run, &server, "127.0.0.1", 9310));
th.join();
#endif
return 0;
}