2025-09-08 14:55:07 +08:00
|
|
|
// main.cpp
|
|
|
|
|
#include "app_config.hpp"
|
|
|
|
|
#include "rtsp_manager.hpp"
|
|
|
|
|
#include "logger.hpp"
|
2025-09-08 15:25:59 +08:00
|
|
|
#include "mqtt_client_wrapper.hpp"
|
|
|
|
|
#include <thread>
|
2025-09-08 14:55:07 +08:00
|
|
|
#include <atomic>
|
|
|
|
|
#include <csignal>
|
|
|
|
|
|
|
|
|
|
std::atomic<bool> g_running(true);
|
|
|
|
|
|
2025-09-10 11:18:29 +08:00
|
|
|
// main.cpp - 修改signalHandler
|
2025-09-10 11:06:42 +08:00
|
|
|
void signalHandler(int signum)
|
2025-09-08 14:55:07 +08:00
|
|
|
{
|
2025-09-10 11:06:42 +08:00
|
|
|
static bool already_called = false;
|
|
|
|
|
if (already_called)
|
|
|
|
|
return;
|
|
|
|
|
already_called = true;
|
|
|
|
|
|
|
|
|
|
LOG_INFO("[MAIN] Received signal " + std::to_string(signum) + ", shutting down...");
|
2025-09-08 14:55:07 +08:00
|
|
|
g_running = false;
|
2025-09-10 11:06:42 +08:00
|
|
|
|
2025-09-10 11:18:29 +08:00
|
|
|
// 停止RTSP循环
|
|
|
|
|
RTSPManager::stop();
|
2025-09-10 11:06:42 +08:00
|
|
|
|
2025-09-10 11:18:29 +08:00
|
|
|
// 记录停止时间
|
|
|
|
|
auto start_time = std::chrono::steady_clock::now();
|
|
|
|
|
|
|
|
|
|
// 等待一段时间让线程退出
|
|
|
|
|
while (std::chrono::steady_clock::now() - start_time < std::chrono::seconds(3))
|
2025-09-10 11:06:42 +08:00
|
|
|
{
|
2025-09-10 11:18:29 +08:00
|
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
2025-09-10 11:06:42 +08:00
|
|
|
}
|
2025-09-10 11:18:29 +08:00
|
|
|
|
|
|
|
|
LOG_INFO("[MAIN] Force exiting after waiting for threads");
|
|
|
|
|
exit(1);
|
2025-09-08 14:55:07 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int main()
|
|
|
|
|
{
|
2025-09-10 11:06:42 +08:00
|
|
|
struct sigaction sigIntHandler;
|
|
|
|
|
sigIntHandler.sa_handler = signalHandler;
|
|
|
|
|
sigemptyset(&sigIntHandler.sa_mask);
|
|
|
|
|
sigIntHandler.sa_flags = 0;
|
|
|
|
|
sigaction(SIGINT, &sigIntHandler, NULL);
|
2025-09-08 14:55:07 +08:00
|
|
|
signal(SIGPIPE, SIG_IGN);
|
|
|
|
|
|
|
|
|
|
// 初始化日志文件
|
2025-09-08 15:32:07 +08:00
|
|
|
Logger::set_log_to_file(get_executable_dir_file_path("app.log"));
|
2025-09-08 14:55:07 +08:00
|
|
|
|
|
|
|
|
try
|
|
|
|
|
{
|
2025-09-08 15:32:07 +08:00
|
|
|
// 从可执行文件所在目录读取配置文件
|
|
|
|
|
g_app_config = AppConfig::load_from_file(get_executable_dir_file_path("config.json"));
|
2025-09-08 14:55:07 +08:00
|
|
|
}
|
|
|
|
|
catch (const std::exception &e)
|
|
|
|
|
{
|
|
|
|
|
LOG_ERROR(std::string("Failed to load config: ") + e.what());
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
2025-09-09 11:08:34 +08:00
|
|
|
// 先在主线程初始化 GStreamer
|
|
|
|
|
RTSPManager::init();
|
|
|
|
|
|
2025-09-08 15:25:59 +08:00
|
|
|
std::thread rtsp_thread([&]()
|
|
|
|
|
{ RTSPManager::start(g_app_config.cameras); });
|
|
|
|
|
std::thread mqtt_thread(mqtt_client_thread_func);
|
|
|
|
|
|
|
|
|
|
// 等待退出信号
|
2025-09-08 15:51:10 +08:00
|
|
|
while (g_running)
|
|
|
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(200));
|
|
|
|
|
|
2025-09-10 11:06:42 +08:00
|
|
|
// 在main函数等待线程结束处添加日志
|
2025-09-08 15:51:10 +08:00
|
|
|
if (rtsp_thread.joinable())
|
2025-09-10 11:06:42 +08:00
|
|
|
{
|
|
|
|
|
LOG_INFO("[MAIN] Waiting for RTSP thread to finish...");
|
2025-09-08 15:51:10 +08:00
|
|
|
rtsp_thread.join();
|
2025-09-10 11:06:42 +08:00
|
|
|
LOG_INFO("[MAIN] RTSP thread finished");
|
|
|
|
|
}
|
2025-09-08 15:51:10 +08:00
|
|
|
if (mqtt_thread.joinable())
|
2025-09-10 11:06:42 +08:00
|
|
|
{
|
|
|
|
|
LOG_INFO("[MAIN] Waiting for MQTT thread to finish...");
|
2025-09-08 15:51:10 +08:00
|
|
|
mqtt_thread.join();
|
2025-09-10 11:06:42 +08:00
|
|
|
LOG_INFO("[MAIN] MQTT thread finished");
|
|
|
|
|
}
|
2025-09-08 14:55:07 +08:00
|
|
|
|
2025-09-08 15:45:22 +08:00
|
|
|
LOG_INFO("[MAIN] Program exited cleanly.");
|
2025-09-08 14:55:07 +08:00
|
|
|
return 0;
|
|
|
|
|
}
|