2025-10-13 13:55:15 +08:00
|
|
|
|
#include "network/tcp_server.h" // 使用重构后的头文件路径
|
|
|
|
|
|
#include "mqtt/mqtt_client.h" // 引入 MQTT 客户端
|
|
|
|
|
|
#include "mqtt/mqtt_router.h" // 引入 MQTT 路由器
|
2025-09-30 18:34:50 +08:00
|
|
|
|
#include "spdlog/spdlog.h"
|
|
|
|
|
|
#include <boost/asio.hpp>
|
2025-10-11 18:24:56 +08:00
|
|
|
|
#include <csignal>
|
2025-09-30 18:34:50 +08:00
|
|
|
|
#include <iostream>
|
|
|
|
|
|
|
2025-10-13 13:55:15 +08:00
|
|
|
|
// 用于 ASIO 服务的全局 io_context
|
2025-10-11 18:24:56 +08:00
|
|
|
|
boost::asio::io_context g_io_context;
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
2025-10-13 13:55:15 +08:00
|
|
|
|
* @brief 处理终止信号 (SIGINT, SIGTERM).
|
2025-10-11 18:24:56 +08:00
|
|
|
|
*
|
2025-10-13 13:55:15 +08:00
|
|
|
|
* 这个函数会优雅地停止 Boost.Asio 的 io_context,
|
|
|
|
|
|
* 这将导致 main() 函数中的 io_context.run() 调用解除阻塞,
|
|
|
|
|
|
* 从而允许程序干净地退出。
|
2025-10-11 18:24:56 +08:00
|
|
|
|
*
|
2025-10-13 13:55:15 +08:00
|
|
|
|
* @param signum 接收到的信号编号。
|
2025-10-11 18:24:56 +08:00
|
|
|
|
*/
|
|
|
|
|
|
void signalHandler(int signum) {
|
|
|
|
|
|
spdlog::warn("Interrupt signal ({}) received. Shutting down.", signum);
|
2025-10-13 13:55:15 +08:00
|
|
|
|
// 向 io_context 提交一个停止事件。这是一种线程安全的方式
|
|
|
|
|
|
// 来告诉 io_context 停止其事件循环。
|
2025-10-11 18:24:56 +08:00
|
|
|
|
g_io_context.stop();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int main(int argc, char* argv[]) {
|
2025-10-13 10:34:20 +08:00
|
|
|
|
|
2025-10-11 18:24:56 +08:00
|
|
|
|
try {
|
2025-10-13 13:55:15 +08:00
|
|
|
|
spdlog::set_level(spdlog::level::debug); // 设置日志级别为 debug,方便调试
|
2025-10-11 18:24:56 +08:00
|
|
|
|
spdlog::info("Edge Proxy starting up...");
|
|
|
|
|
|
} catch (const spdlog::spdlog_ex& ex) {
|
|
|
|
|
|
std::cerr << "Log initialization failed: " << ex.what() << std::endl;
|
|
|
|
|
|
return 1;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-10-13 13:55:15 +08:00
|
|
|
|
// 注册信号处理器
|
2025-10-11 18:24:56 +08:00
|
|
|
|
signal(SIGINT, signalHandler);
|
|
|
|
|
|
signal(SIGTERM, signalHandler);
|
|
|
|
|
|
|
2025-10-11 14:06:38 +08:00
|
|
|
|
try {
|
2025-10-13 13:55:15 +08:00
|
|
|
|
// --- 1. 初始化 TCP 服务 ---
|
|
|
|
|
|
constexpr uint16_t tcp_port = 8888;
|
|
|
|
|
|
TCPServer tcp_server(g_io_context, tcp_port);
|
2025-10-11 18:24:56 +08:00
|
|
|
|
|
2025-10-13 13:55:15 +08:00
|
|
|
|
// --- 2. 初始化 MQTT 服务 ---
|
|
|
|
|
|
// a. 创建 MQTT 客户端实例并连接到 Broker
|
|
|
|
|
|
MqttClient mqtt_client("tcp://mqtt-broker:1883", "edge-proxy-main-client");
|
|
|
|
|
|
mqtt_client.connect();
|
|
|
|
|
|
|
|
|
|
|
|
// b. 创建 MQTT 路由逻辑实例,并将客户端注入进去
|
|
|
|
|
|
MqttRouter mqtt_router(mqtt_client);
|
|
|
|
|
|
|
|
|
|
|
|
// c. 启动 MQTT 路由的订阅逻辑
|
|
|
|
|
|
mqtt_router.start();
|
|
|
|
|
|
|
|
|
|
|
|
// --- 3. 启动事件循环 ---
|
|
|
|
|
|
spdlog::info("All services are running. Press Ctrl+C to exit.");
|
|
|
|
|
|
// g_io_context.run() 将会阻塞在这里,处理 TCP 相关的异步事件,
|
|
|
|
|
|
// 直到 signalHandler 调用 g_io_context.stop()。
|
|
|
|
|
|
// 同时,Paho MQTT 库在自己的后台线程中处理 MQTT 通信。
|
2025-10-11 18:24:56 +08:00
|
|
|
|
g_io_context.run();
|
|
|
|
|
|
|
2025-10-13 13:55:15 +08:00
|
|
|
|
// --- 4. 准备关闭 ---
|
|
|
|
|
|
// 当 run() 返回后 (因为收到了信号),在退出前断开 MQTT 连接
|
|
|
|
|
|
spdlog::info("Shutting down MQTT client...");
|
|
|
|
|
|
mqtt_client.disconnect();
|
|
|
|
|
|
|
2025-10-11 18:24:56 +08:00
|
|
|
|
} catch (const std::exception& e) {
|
|
|
|
|
|
spdlog::critical("An unhandled exception occurred: {}", e.what());
|
|
|
|
|
|
return 1;
|
2025-09-30 18:34:50 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-10-11 18:24:56 +08:00
|
|
|
|
spdlog::info("Server has been shut down gracefully. Exiting.");
|
2025-09-30 18:34:50 +08:00
|
|
|
|
return 0;
|
|
|
|
|
|
}
|