add old lci module
This commit is contained in:
1 parent
38a6e815f0
commit
8499631091
171 files changed
+25562
No files matched your search
@@ -0,0 +1,82 @@
|
||||
#pragma once
|
||||
#include <httplib.h> // libcpp-httplib-dev
|
||||
#include <nlohmann/json.hpp> //
|
||||
#include <iostream>
|
||||
#include <filesystem> //
|
||||
#include <stdexcept>
|
||||
namespace fs = std::filesystem;
|
||||
/* 这里的类型是HTTP服务器要设置的回调函数的类型 */
|
||||
using Handler = std::function<void(const httplib::Request&, httplib::Response&)>;
|
||||
namespace qing {
|
||||
/* NOTE: 不要删除该类,这个抽象成能够方便重构 */
|
||||
class Http { /* 超文本传输协议(HTTP)服务器类 */
|
||||
public:
|
||||
/* 初始化各个变量 */
|
||||
Http(std::string addr, int port): addr(addr), port(port) {}
|
||||
|
||||
/* 运行服务器,失败抛出异常 */
|
||||
void run() {
|
||||
//printAddr(); /* 在日志里打印更好 */
|
||||
if (!svr.listen(addr.c_str(), port))
|
||||
throw StartServerFailed("");
|
||||
}
|
||||
|
||||
/* 终止服务器 */
|
||||
void stop() { svr.stop(); }
|
||||
|
||||
|
||||
/*
|
||||
* 设置路由和对应的处理函数
|
||||
*
|
||||
* FIXME: 使用一个方法实现两个功能
|
||||
*/
|
||||
void get (std::string path, Handler handler) { svr.Get(path, handler); }
|
||||
void post(std::string path, Handler handler) { svr.Post(path, handler); }
|
||||
|
||||
/*
|
||||
* 打印地址
|
||||
*
|
||||
* FIXME: 把这个函数的具体功能放到类的外部
|
||||
*/
|
||||
std::string printAddr() { return std::string("pmcd now listenning on this address: http://") + addr + ":" + std::to_string(port); }
|
||||
|
||||
/* 获取当前执行文件目录 */
|
||||
//static std::string getCurrentDirectory() {
|
||||
// fs::path currentPath = fs::absolute(__FILE__);
|
||||
// return currentPath.parent_path().string();
|
||||
//}
|
||||
|
||||
// 读取文本文件的所有内容
|
||||
//static std::string readFile(const std::string& filePath) {
|
||||
// std::ifstream file(filePath); // 创建一个输入文件流对象,用于读取文件
|
||||
// if (!file) {
|
||||
// std::cerr << "无法打开文件:" << filePath << std::endl;
|
||||
// return "";
|
||||
// }
|
||||
// std::string content((std::istreambuf_iterator<char>(file)), std::istreambuf_iterator<char>()); /* 使用迭代器读取文件内容到字符串 */
|
||||
// file.close();
|
||||
// return content;
|
||||
//}
|
||||
|
||||
class Http_Error: public std::exception { /* HTTP 异常类 */
|
||||
private:
|
||||
std::string message;
|
||||
public:
|
||||
explicit Http_Error(const std::string& msg): message(msg) {}
|
||||
const char* what() const noexcept override {
|
||||
return message.c_str();
|
||||
}
|
||||
};
|
||||
|
||||
class StartServerFailed: public Http_Error { /* 开始服务失败 */
|
||||
public:
|
||||
StartServerFailed(const std::string& msg): Http_Error(msg) {}
|
||||
};
|
||||
|
||||
|
||||
private:
|
||||
httplib::Server svr; /* 创建HTTP服务器对象(如果需要HTTPS,则使用SSLServer */
|
||||
std::string addr; /* 服务地址 */
|
||||
int port; /* 端口 */
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,151 @@
|
||||
#ifndef PMC_HTTP_CLIENT_HPP
|
||||
#define PMC_HTTP_CLIENT_HPP
|
||||
|
||||
#include <string>
|
||||
#include <functional>
|
||||
#include <curl/curl.h>
|
||||
#include <iostream>
|
||||
|
||||
namespace pmc::net {
|
||||
|
||||
class HttpClient {
|
||||
public:
|
||||
HttpClient() {
|
||||
std::cout << "HttpClient构造函数: 开始初始化" << std::endl;
|
||||
curl_ = curl_easy_init();
|
||||
if (!curl_) {
|
||||
throw std::runtime_error("Failed to initialize CURL");
|
||||
}
|
||||
std::cout << "HttpClient构造函数: 初始化完成" << std::endl;
|
||||
}
|
||||
|
||||
~HttpClient() {
|
||||
std::cout << "HttpClient析构函数: 开始清理" << std::endl;
|
||||
if (curl_) {
|
||||
curl_easy_cleanup(curl_);
|
||||
}
|
||||
if (headers_) {
|
||||
curl_slist_free_all(headers_);
|
||||
}
|
||||
std::cout << "HttpClient析构函数: 清理完成" << std::endl;
|
||||
}
|
||||
|
||||
void set_header(const std::string& header) {
|
||||
std::cout << "set_header: 添加header: " << header << std::endl;
|
||||
headers_ = curl_slist_append(headers_, header.c_str());
|
||||
}
|
||||
|
||||
// 同步流式请求
|
||||
void post_stream_sync(const std::string& url, const std::string& data, std::function<void(const std::string&)> callback) {
|
||||
std::cout << "post_stream_sync: 开始发送流式请求到 " << url << std::endl;
|
||||
|
||||
if (!curl_) {
|
||||
throw std::runtime_error("CURL not initialized");
|
||||
}
|
||||
|
||||
// 重置CURL句柄
|
||||
curl_easy_reset(curl_);
|
||||
|
||||
// 设置URL
|
||||
curl_easy_setopt(curl_, CURLOPT_URL, url.c_str());
|
||||
|
||||
// 设置POST请求
|
||||
curl_easy_setopt(curl_, CURLOPT_POST, 1L);
|
||||
curl_easy_setopt(curl_, CURLOPT_POSTFIELDS, data.c_str());
|
||||
curl_easy_setopt(curl_, CURLOPT_POSTFIELDSIZE, data.size());
|
||||
|
||||
// 设置请求头
|
||||
curl_easy_setopt(curl_, CURLOPT_HTTPHEADER, headers_);
|
||||
|
||||
// 设置流式回调函数
|
||||
std::string buffer;
|
||||
auto data_pair = std::make_pair(&buffer, &callback);
|
||||
std::cout << "post_stream_sync: 数据对创建完成" << std::endl;
|
||||
|
||||
curl_easy_setopt(curl_, CURLOPT_WRITEFUNCTION, stream_write_callback);
|
||||
curl_easy_setopt(curl_, CURLOPT_WRITEDATA, &data_pair);
|
||||
|
||||
// 设置超时和连接选项
|
||||
curl_easy_setopt(curl_, CURLOPT_TIMEOUT, 30L);
|
||||
curl_easy_setopt(curl_, CURLOPT_CONNECTTIMEOUT, 10L);
|
||||
|
||||
// 执行请求
|
||||
std::cout << "post_stream_sync: 执行请求" << std::endl;
|
||||
CURLcode res = curl_easy_perform(curl_);
|
||||
std::cout << "post_stream_sync: 数据对清理完成" << std::endl;
|
||||
|
||||
if (res != CURLE_OK) {
|
||||
std::cout << "post_stream_sync: CURL错误: " << curl_easy_strerror(res) << std::endl;
|
||||
throw std::runtime_error(std::string("CURL error: ") + curl_easy_strerror(res));
|
||||
}
|
||||
|
||||
std::cout << "post_stream_sync: 请求成功" << std::endl;
|
||||
}
|
||||
|
||||
private:
|
||||
CURL* curl_ = nullptr;
|
||||
struct curl_slist* headers_ = nullptr;
|
||||
|
||||
static size_t stream_write_callback(char* ptr, size_t size, size_t nmemb, void* userdata) {
|
||||
// userdata指向一个std::pair<std::string*, std::function<void(const std::string&)>*>
|
||||
auto* data_pair = static_cast<std::pair<std::string*, std::function<void(const std::string&)>*>*>(userdata);
|
||||
if (!data_pair || !data_pair->first || !data_pair->second) {
|
||||
std::cout << "stream_write_callback: 无效的用户数据" << std::endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::string& buffer = *(data_pair->first);
|
||||
std::function<void(const std::string&)>& callback = *(data_pair->second);
|
||||
size_t total_size = size * nmemb;
|
||||
|
||||
std::cout << "stream_write_callback: 收到 " << total_size << " 字节数据" << std::endl;
|
||||
|
||||
// 将数据追加到缓冲区
|
||||
buffer.append(ptr, total_size);
|
||||
|
||||
// 打印原始数据(用于调试)
|
||||
std::string raw_data(ptr, total_size);
|
||||
std::cout << "stream_write_callback: 原始数据: " << raw_data << std::endl;
|
||||
|
||||
// 处理流式数据(按行处理Server-Sent Events格式)
|
||||
size_t pos = 0;
|
||||
size_t newline_pos;
|
||||
|
||||
while ((newline_pos = buffer.find('\n', pos)) != std::string::npos) {
|
||||
std::string line = buffer.substr(pos, newline_pos - pos);
|
||||
pos = newline_pos + 1;
|
||||
|
||||
std::cout << "stream_write_callback: 处理行: " << line << std::endl;
|
||||
|
||||
// 处理SSE格式的数据(以"data: "开头)
|
||||
if (line.rfind("data: ", 0) == 0) {
|
||||
std::string json_str = line.substr(6);
|
||||
|
||||
if (json_str == "[DONE]") {
|
||||
std::cout << "stream_write_callback: 收到 [DONE]" << std::endl;
|
||||
callback("[[流式传输完成]]");
|
||||
continue;
|
||||
}
|
||||
|
||||
// 调用回调函数处理JSON数据
|
||||
std::cout << "stream_write_callback: 调用回调,数据长度: " << json_str.length() << std::endl;
|
||||
callback(json_str);
|
||||
} else if (!line.empty()) {
|
||||
// 如果不是SSE格式,直接传递给回调(可能是错误消息)
|
||||
std::cout << "stream_write_callback: 非SSE数据,直接传递: " << line << std::endl;
|
||||
callback(line);
|
||||
}
|
||||
}
|
||||
|
||||
// 移除已处理的数据
|
||||
if (pos > 0) {
|
||||
buffer.erase(0, pos);
|
||||
}
|
||||
|
||||
return total_size;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace pmc::net
|
||||
|
||||
#endif // PMC_HTTP_CLIENT_HPP
|
||||
@@ -0,0 +1,193 @@
|
||||
#ifndef HTTPSERVER_HPP
|
||||
#define HTTPSERVER_HPP
|
||||
|
||||
#include <boost/asio.hpp>
|
||||
#include <boost/beast.hpp>
|
||||
#include <boost/beast/http.hpp>
|
||||
#include <boost/beast/version.hpp>
|
||||
#include <boost/asio/ip/tcp.hpp>
|
||||
#include <boost/asio/strand.hpp>
|
||||
#include <boost/config.hpp>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <functional>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
#include <thread>
|
||||
#include <atomic>
|
||||
|
||||
namespace beast = boost::beast;
|
||||
namespace http = beast::http;
|
||||
namespace asio = boost::asio;
|
||||
using tcp = boost::asio::ip::tcp;
|
||||
|
||||
namespace pmc {
|
||||
namespace net {
|
||||
|
||||
/**
|
||||
* @brief HTTP请求处理器类型定义
|
||||
*
|
||||
* 处理HTTP请求并返回响应
|
||||
*/
|
||||
using HttpRequestHandler = std::function<http::response<http::string_body>(
|
||||
const http::request<http::string_body>&,
|
||||
const std::unordered_map<std::string, std::string>&)>;
|
||||
|
||||
/**
|
||||
* @brief 中间件处理器类型定义
|
||||
*
|
||||
* 用于处理请求链的中间件
|
||||
*/
|
||||
using MiddlewareHandler = std::function<bool(
|
||||
const http::request<http::string_body>&,
|
||||
http::response<http::string_body>&,
|
||||
const std::unordered_map<std::string, std::string>&)>;
|
||||
|
||||
/**
|
||||
* @brief HTTP服务器类(合并增强版)
|
||||
*
|
||||
* 基于boost::asio和boost::beast的异步HTTP服务器
|
||||
* 结合了原始版本的易用性和修复版本的功能完整性
|
||||
*/
|
||||
class HttpServer {
|
||||
public:
|
||||
/**
|
||||
* @brief 构造函数(监听所有接口)
|
||||
* @param port 监听端口
|
||||
* @param threads 工作线程数
|
||||
*/
|
||||
explicit HttpServer(unsigned short port, unsigned int threads = 1);
|
||||
|
||||
/**
|
||||
* @brief 构造函数(指定监听地址)
|
||||
* @param address 监听IP地址(如 "0.0.0.0" 或 "127.0.0.1")
|
||||
* @param port 监听端口
|
||||
* @param threads 工作线程数
|
||||
*/
|
||||
explicit HttpServer(const std::string& address, unsigned short port, unsigned int threads = 1);
|
||||
|
||||
/**
|
||||
* @brief 析构函数
|
||||
*/
|
||||
~HttpServer();
|
||||
|
||||
/**
|
||||
* @brief 启动服务器
|
||||
*/
|
||||
void start();
|
||||
|
||||
/**
|
||||
* @brief 停止服务器
|
||||
*/
|
||||
void stop();
|
||||
|
||||
/**
|
||||
* @brief 注册GET请求处理器
|
||||
* @param path 请求路径
|
||||
* @param handler 请求处理器
|
||||
*/
|
||||
void get(const std::string& path, HttpRequestHandler handler);
|
||||
|
||||
/**
|
||||
* @brief 注册POST请求处理器
|
||||
* @param path 请求路径
|
||||
* @param handler 请求处理器
|
||||
*/
|
||||
void post(const std::string& path, HttpRequestHandler handler);
|
||||
|
||||
/**
|
||||
* @brief 注册PUT请求处理器
|
||||
* @param path 请求路径
|
||||
* @param handler 请求处理器
|
||||
*/
|
||||
void put(const std::string& path, HttpRequestHandler handler);
|
||||
|
||||
/**
|
||||
* @brief 注册DELETE请求处理器
|
||||
* @param path 请求路径
|
||||
* @param handler 请求处理器
|
||||
*/
|
||||
void del(const std::string& path, HttpRequestHandler handler);
|
||||
|
||||
/**
|
||||
* @brief 注册中间件
|
||||
* @param middleware 中间件处理器
|
||||
*/
|
||||
void use(MiddlewareHandler middleware);
|
||||
|
||||
/**
|
||||
* @brief 设置静态文件目录
|
||||
* @param path 静态文件目录路径
|
||||
*/
|
||||
void setStaticDirectory(const std::string& path);
|
||||
|
||||
/**
|
||||
* @brief 获取服务器状态
|
||||
* @return 服务器是否正在运行
|
||||
*/
|
||||
bool isRunning() const;
|
||||
|
||||
/**
|
||||
* @brief 获取服务器端口
|
||||
* @return 服务器监听端口
|
||||
*/
|
||||
unsigned short getPort() const;
|
||||
|
||||
/**
|
||||
* @brief 获取服务器监听地址
|
||||
* @return 服务器监听地址
|
||||
*/
|
||||
std::string getAddress() const;
|
||||
|
||||
/**
|
||||
* @brief 运行服务器(阻塞调用)- 从原始版本继承
|
||||
*/
|
||||
void run();
|
||||
|
||||
/**
|
||||
* @brief 显示服务器状态信息 - 从原始版本继承
|
||||
*/
|
||||
void showStatus() const;
|
||||
|
||||
private:
|
||||
// 内部类声明
|
||||
class Session;
|
||||
class Listener;
|
||||
|
||||
// 服务器配置
|
||||
std::string address_;
|
||||
unsigned short port_;
|
||||
unsigned int threads_;
|
||||
std::atomic<bool> running_{false};
|
||||
|
||||
// Boost.Asio上下文
|
||||
std::unique_ptr<asio::io_context> ioc_;
|
||||
|
||||
// 网络组件
|
||||
std::shared_ptr<Listener> listener_;
|
||||
std::vector<std::thread> worker_threads_;
|
||||
|
||||
// 路由表
|
||||
std::unordered_map<std::string, HttpRequestHandler> get_handlers_;
|
||||
std::unordered_map<std::string, HttpRequestHandler> post_handlers_;
|
||||
std::unordered_map<std::string, HttpRequestHandler> put_handlers_;
|
||||
std::unordered_map<std::string, HttpRequestHandler> delete_handlers_;
|
||||
|
||||
// 中间件链
|
||||
std::vector<MiddlewareHandler> middlewares_;
|
||||
|
||||
// 静态文件目录
|
||||
std::string static_directory_;
|
||||
|
||||
// 内部方法
|
||||
std::unordered_map<std::string, std::string> parseQueryParams(const std::string& query);
|
||||
|
||||
// 请求处理
|
||||
http::response<http::string_body> handleRequest(const http::request<http::string_body>& req);
|
||||
};
|
||||
|
||||
} // namespace net
|
||||
} // namespace pmc
|
||||
|
||||
#endif // HTTPSERVER_HPP
|
||||
@@ -0,0 +1,63 @@
|
||||
#ifndef PMC_NET_WEBSOCKET_CLIENT_HPP
|
||||
#define PMC_NET_WEBSOCKET_CLIENT_HPP
|
||||
|
||||
#include "WebSocketClientBase.hpp"
|
||||
|
||||
namespace pmc {
|
||||
namespace net {
|
||||
|
||||
/**
|
||||
* @brief 基于 Boost.Beast 的异步 WebSocket 客户端(非 SSL 版本)
|
||||
*/
|
||||
class WebSocketClient : public WebSocketClientBase {
|
||||
public:
|
||||
/**
|
||||
* @brief 构造函数
|
||||
* @param host 服务器主机名或 IP 地址
|
||||
* @param port 服务器端口号
|
||||
* @param path WebSocket 路径(默认 "/")
|
||||
*/
|
||||
WebSocketClient(const std::string& host, const std::string& port, const std::string& path = "/");
|
||||
|
||||
/**
|
||||
* @brief 析构函数
|
||||
*/
|
||||
~WebSocketClient();
|
||||
|
||||
// 实现 WebSocketClientBase 接口
|
||||
void setMessageCallback(MessageCallback callback) override;
|
||||
void setErrorCallback(ErrorCallback callback) override;
|
||||
void setConnectCallback(ConnectCallback callback) override;
|
||||
void setCloseCallback(CloseCallback callback) override;
|
||||
|
||||
bool connect(int timeout_ms = 5000) override;
|
||||
void disconnect() override;
|
||||
bool isConnected() const override;
|
||||
|
||||
bool send(const std::string& message) override;
|
||||
bool sendBinary(const void* data, size_t size) override;
|
||||
|
||||
void setAutoReconnect(bool enable, int interval_ms = 3000) override;
|
||||
void setHeartbeatInterval(int interval_ms = 30000) override;
|
||||
|
||||
std::string getHost() const override;
|
||||
std::string getPort() const override;
|
||||
std::string getPath() const override;
|
||||
|
||||
// SSL/TLS 相关(非 SSL 版本返回默认值)
|
||||
bool isSecure() const override { return false; }
|
||||
void setVerifyCertificate(bool verify) override { /* 忽略 */ }
|
||||
void setCertificateFile(const std::string& cert_file) override { /* 忽略 */ }
|
||||
void setPrivateKeyFile(const std::string& key_file) override { /* 忽略 */ }
|
||||
void setCertificateAuthorityFile(const std::string& ca_file) override { /* 忽略 */ }
|
||||
|
||||
private:
|
||||
// 前向声明实现类
|
||||
class Impl;
|
||||
std::unique_ptr<Impl> impl_;
|
||||
};
|
||||
|
||||
} // namespace net
|
||||
} // namespace pmc
|
||||
|
||||
#endif // PMC_NET_WEBSOCKET_CLIENT_HPP
|
||||
@@ -0,0 +1,61 @@
|
||||
#ifndef PMC_NET_WEBSOCKET_CLIENT_BASE_HPP
|
||||
#define PMC_NET_WEBSOCKET_CLIENT_BASE_HPP
|
||||
|
||||
#include <string>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
|
||||
namespace pmc {
|
||||
namespace net {
|
||||
|
||||
/**
|
||||
* @brief WebSocket 客户端基类
|
||||
*
|
||||
* 定义所有 WebSocket 客户端的公共接口
|
||||
*/
|
||||
class WebSocketClientBase {
|
||||
public:
|
||||
// 回调函数类型
|
||||
using MessageCallback = std::function<void(const std::string&)>;
|
||||
using ErrorCallback = std::function<void(const std::string&)>;
|
||||
using ConnectCallback = std::function<void(bool)>;
|
||||
using CloseCallback = std::function<void()>;
|
||||
|
||||
virtual ~WebSocketClientBase() = default;
|
||||
|
||||
// 回调函数设置
|
||||
virtual void setMessageCallback(MessageCallback callback) = 0;
|
||||
virtual void setErrorCallback(ErrorCallback callback) = 0;
|
||||
virtual void setConnectCallback(ConnectCallback callback) = 0;
|
||||
virtual void setCloseCallback(CloseCallback callback) = 0;
|
||||
|
||||
// 连接管理
|
||||
virtual bool connect(int timeout_ms = 5000) = 0;
|
||||
virtual void disconnect() = 0;
|
||||
virtual bool isConnected() const = 0;
|
||||
|
||||
// 消息发送
|
||||
virtual bool send(const std::string& message) = 0;
|
||||
virtual bool sendBinary(const void* data, size_t size) = 0;
|
||||
|
||||
// 配置选项
|
||||
virtual void setAutoReconnect(bool enable, int interval_ms = 3000) = 0;
|
||||
virtual void setHeartbeatInterval(int interval_ms = 30000) = 0;
|
||||
|
||||
// 信息获取
|
||||
virtual std::string getHost() const = 0;
|
||||
virtual std::string getPort() const = 0;
|
||||
virtual std::string getPath() const = 0;
|
||||
|
||||
// SSL/TLS 相关
|
||||
virtual bool isSecure() const = 0;
|
||||
virtual void setVerifyCertificate(bool verify) = 0;
|
||||
virtual void setCertificateFile(const std::string& cert_file) = 0;
|
||||
virtual void setPrivateKeyFile(const std::string& key_file) = 0;
|
||||
virtual void setCertificateAuthorityFile(const std::string& ca_file) = 0;
|
||||
};
|
||||
|
||||
} // namespace net
|
||||
} // namespace pmc
|
||||
|
||||
#endif // PMC_NET_WEBSOCKET_CLIENT_BASE_HPP
|
||||
@@ -0,0 +1,85 @@
|
||||
#ifndef PMC_NET_WEBSOCKET_CLIENT_SSL_HPP
|
||||
#define PMC_NET_WEBSOCKET_CLIENT_SSL_HPP
|
||||
|
||||
#include "WebSocketClientBase.hpp"
|
||||
#include <string>
|
||||
#include <memory>
|
||||
|
||||
namespace pmc {
|
||||
namespace net {
|
||||
|
||||
/**
|
||||
* @brief 基于 Boost.Beast 的异步 WebSocket 客户端(SSL/TLS 版本)
|
||||
*
|
||||
* 支持安全的 WebSocket 连接(wss://)
|
||||
*/
|
||||
class WebSocketClientSSL : public WebSocketClientBase {
|
||||
public:
|
||||
/**
|
||||
* @brief 构造函数
|
||||
* @param host 服务器主机名或 IP 地址
|
||||
* @param port 服务器端口号(通常为 443)
|
||||
* @param path WebSocket 路径(默认 "/")
|
||||
*/
|
||||
WebSocketClientSSL(const std::string& host, const std::string& port, const std::string& path = "/");
|
||||
|
||||
/**
|
||||
* @brief 析构函数
|
||||
*/
|
||||
~WebSocketClientSSL();
|
||||
|
||||
// 实现 WebSocketClientBase 接口
|
||||
void setMessageCallback(MessageCallback callback) override;
|
||||
void setErrorCallback(ErrorCallback callback) override;
|
||||
void setConnectCallback(ConnectCallback callback) override;
|
||||
void setCloseCallback(CloseCallback callback) override;
|
||||
|
||||
bool connect(int timeout_ms = 5000) override;
|
||||
void disconnect() override;
|
||||
bool isConnected() const override;
|
||||
|
||||
bool send(const std::string& message) override;
|
||||
bool sendBinary(const void* data, size_t size) override;
|
||||
|
||||
void setAutoReconnect(bool enable, int interval_ms = 3000) override;
|
||||
void setHeartbeatInterval(int interval_ms = 30000) override;
|
||||
|
||||
std::string getHost() const override;
|
||||
std::string getPort() const override;
|
||||
std::string getPath() const override;
|
||||
|
||||
// SSL/TLS 相关方法
|
||||
bool isSecure() const override { return true; }
|
||||
void setVerifyCertificate(bool verify) override;
|
||||
void setCertificateFile(const std::string& cert_file) override;
|
||||
void setPrivateKeyFile(const std::string& key_file) override;
|
||||
void setCertificateAuthorityFile(const std::string& ca_file) override;
|
||||
|
||||
/**
|
||||
* @brief 设置 SSL 上下文选项
|
||||
* @param options SSL 上下文选项
|
||||
*/
|
||||
void setSSLContextOptions(long options);
|
||||
|
||||
/**
|
||||
* @brief 设置密码列表
|
||||
* @param ciphers 密码列表字符串
|
||||
*/
|
||||
void setCiphers(const std::string& ciphers);
|
||||
|
||||
/**
|
||||
* @brief 设置 SNI 主机名
|
||||
* @param sni_hostname SNI 主机名
|
||||
*/
|
||||
void setSNIHostname(const std::string& sni_hostname);
|
||||
|
||||
private:
|
||||
// 前向声明实现类
|
||||
class Impl;
|
||||
std::unique_ptr<Impl> impl_;
|
||||
};
|
||||
|
||||
} // namespace net
|
||||
} // namespace pmc
|
||||
|
||||
#endif // PMC_NET_WEBSOCKET_CLIENT_SSL_HPP
|
||||
@@ -0,0 +1,176 @@
|
||||
// WebSocketServer.hpp - WebSocket服务器头文件
|
||||
// 基于Boost.Beast和Boost.Asio
|
||||
|
||||
#ifndef PMC_NET_WEBSOCKETSERVER_HPP
|
||||
#define PMC_NET_WEBSOCKETSERVER_HPP
|
||||
|
||||
#include <functional>
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include <unordered_map>
|
||||
#include <mutex>
|
||||
#include <atomic>
|
||||
#include <vector>
|
||||
#include <thread>
|
||||
#include <boost/asio/io_context.hpp>
|
||||
#include <boost/asio/ip/tcp.hpp>
|
||||
|
||||
namespace pmc::net {
|
||||
|
||||
/**
|
||||
* @brief WebSocket连接处理器类型定义
|
||||
*
|
||||
* 处理WebSocket连接建立后的消息收发
|
||||
*/
|
||||
using WebSocketMessageHandler = std::function<void(
|
||||
const std::string& clientId,
|
||||
const std::string& message,
|
||||
std::function<void(const std::string&)> sendCallback)>;
|
||||
|
||||
/**
|
||||
* @brief WebSocket连接回调类型定义
|
||||
*/
|
||||
using WebSocketConnectHandler = std::function<void(
|
||||
const std::string& clientId,
|
||||
const std::string& remoteAddress)>;
|
||||
|
||||
/**
|
||||
* @brief WebSocket断开连接回调类型定义
|
||||
*/
|
||||
using WebSocketDisconnectHandler = std::function<void(
|
||||
const std::string& clientId)>;
|
||||
|
||||
/**
|
||||
* @brief WebSocket服务器类
|
||||
*
|
||||
* 基于Boost.Beast和Boost.Asio实现的WebSocket服务器
|
||||
*/
|
||||
class WebSocketServer {
|
||||
public:
|
||||
/**
|
||||
* @brief 构造函数
|
||||
* @param port 监听端口
|
||||
* @param threads 线程数(默认2)
|
||||
*/
|
||||
WebSocketServer(unsigned short port, unsigned int threads = 2);
|
||||
|
||||
/**
|
||||
* @brief 析构函数
|
||||
*/
|
||||
~WebSocketServer();
|
||||
|
||||
/**
|
||||
* @brief 启动服务器
|
||||
*/
|
||||
void start();
|
||||
|
||||
/**
|
||||
* @brief 停止服务器
|
||||
*/
|
||||
void stop();
|
||||
|
||||
/**
|
||||
* @brief 注册消息处理器
|
||||
* @param path 路径(用于路由)
|
||||
* @param handler 消息处理器
|
||||
*/
|
||||
void onMessage(const std::string& path, WebSocketMessageHandler handler);
|
||||
|
||||
/**
|
||||
* @brief 注册连接处理器
|
||||
* @param handler 连接处理器
|
||||
*/
|
||||
void onConnect(WebSocketConnectHandler handler);
|
||||
|
||||
/**
|
||||
* @brief 注册断开连接处理器
|
||||
* @param handler 断开连接处理器
|
||||
*/
|
||||
void onDisconnect(WebSocketDisconnectHandler handler);
|
||||
|
||||
/**
|
||||
* @brief 向指定客户端发送消息
|
||||
* @param clientId 客户端ID
|
||||
* @param message 消息内容
|
||||
* @return 是否发送成功
|
||||
*/
|
||||
bool sendToClient(const std::string& clientId, const std::string& message);
|
||||
|
||||
/**
|
||||
* @brief 向所有客户端广播消息
|
||||
* @param message 消息内容
|
||||
* @return 成功发送的客户端数量
|
||||
*/
|
||||
size_t broadcast(const std::string& message);
|
||||
|
||||
/**
|
||||
* @brief 断开指定客户端连接
|
||||
* @param clientId 客户端ID
|
||||
*/
|
||||
void disconnectClient(const std::string& clientId);
|
||||
|
||||
/**
|
||||
* @brief 获取当前连接的客户端数量
|
||||
* @return 客户端数量
|
||||
*/
|
||||
size_t getClientCount() const;
|
||||
|
||||
/**
|
||||
* @brief 获取服务器是否正在运行
|
||||
* @return 运行状态
|
||||
*/
|
||||
bool isRunning() const { return running_; }
|
||||
|
||||
/**
|
||||
* @brief 获取服务器监听端口
|
||||
* @return 端口号
|
||||
*/
|
||||
unsigned short getPort() const { return port_; }
|
||||
|
||||
private:
|
||||
// 内部Session类
|
||||
class Session;
|
||||
|
||||
// 内部Listener类
|
||||
class Listener;
|
||||
|
||||
// 内部实现结构体
|
||||
struct Impl {
|
||||
boost::asio::io_context ioc_;
|
||||
std::shared_ptr<Listener> listener_;
|
||||
std::vector<std::thread> threads_;
|
||||
};
|
||||
|
||||
// 服务器配置
|
||||
unsigned short port_;
|
||||
unsigned int threads_;
|
||||
std::atomic<bool> running_{false};
|
||||
|
||||
// 内部实现
|
||||
std::unique_ptr<Impl> impl_;
|
||||
|
||||
// 生成客户端ID
|
||||
std::string generateClientId() const;
|
||||
|
||||
// 添加客户端
|
||||
void addClient(const std::string& clientId, std::shared_ptr<Session> session);
|
||||
|
||||
// 移除客户端
|
||||
void removeClient(const std::string& clientId);
|
||||
|
||||
// 获取客户端Session
|
||||
std::shared_ptr<Session> getClient(const std::string& clientId);
|
||||
|
||||
// 回调函数
|
||||
std::unordered_map<std::string, WebSocketMessageHandler> messageHandlers_;
|
||||
WebSocketConnectHandler connectHandler_;
|
||||
WebSocketDisconnectHandler disconnectHandler_;
|
||||
|
||||
// 客户端管理
|
||||
mutable std::mutex clientsMutex_;
|
||||
std::unordered_map<std::string, std::shared_ptr<Session>> clients_;
|
||||
};
|
||||
|
||||
} // namespace pmc::net
|
||||
|
||||
#endif // PMC_NET_WEBSOCKETSERVER_HPP
|
||||
Reference in new issue
Block a user