From f06e9b5c7fc2fd27516d22ab663fbab6d92082ad Mon Sep 17 00:00:00 2001 From: GuanYuankai Date: Thu, 16 Oct 2025 09:05:24 +0000 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E8=AE=BE=E5=A4=87=E5=AE=9E?= =?UTF-8?q?=E6=97=B6=E7=8A=B6=E6=80=81=E7=BC=93=E5=AD=98=E6=A8=A1=E5=9D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config/devices.json | 2 +- src/dataCache/live_data_cache.h | 38 +++++++++++++++++++++++++++++++++ src/main.cpp | 8 ++++--- src/web/web_server.cc | 24 +++++++++++++++++---- src/web/web_server.h | 9 +++++++- 5 files changed, 72 insertions(+), 9 deletions(-) create mode 100644 src/dataCache/live_data_cache.h diff --git a/config/devices.json b/config/devices.json index 690950f..73bc846 100644 --- a/config/devices.json +++ b/config/devices.json @@ -1,7 +1,7 @@ { "modbus_rtu_devices": [ { - "enabled": false, + "enabled": true, "device_id": "rtu_temp_sensor_lab", "port_path": "/dev/ttyS7", "baud_rate": 9600, diff --git a/src/dataCache/live_data_cache.h b/src/dataCache/live_data_cache.h new file mode 100644 index 0000000..fb271a3 --- /dev/null +++ b/src/dataCache/live_data_cache.h @@ -0,0 +1,38 @@ +#ifndef LIVE_DATA_CACHE_H +#define LIVE_DATA_CACHE_H + +#include +#include +#include + +/** + * @brief 一个线程安全的、用于存储所有设备最新上报数据的内存缓存。 + * 设计为单例或共享对象,供数据回调和API服务同时访问。 + */ +class LiveDataCache { +public: + /** + * @brief 更新或插入一个设备的最新数据。 + * @param device_id 设备的唯一ID。 + * @param json_data 设备上报的完整JSON数据字符串。 + */ + void update_data(const std::string& device_id, const std::string& json_data) { + std::lock_guard lock(m_mutex); + m_latest_data[device_id] = json_data; + } + + /** + * @brief 获取所有设备最新数据的快照。 + * @return 一个从设备ID到其最新JSON数据的map。 + */ + std::map get_all_data() const { + std::lock_guard lock(m_mutex); + return m_latest_data; // 返回一个副本以保证线程安全 + } + +private: + mutable std::mutex m_mutex; + std::map m_latest_data; +}; + +#endif // LIVE_DATA_CACHE_H \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index 2aa6208..08bcc14 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -9,6 +9,7 @@ #include "dataCache/data_cache.h" #include "dataCache/cache_uploader.h" #include "web/web_server.h" +#include "dataCache/live_data_cache.h" #include #include @@ -53,9 +54,11 @@ int main(int argc, char* argv[]) { } try { - DataCache data_cache; + DataCache data_cache; + LiveDataCache live_data_cache; MqttClient mqtt_client("tcp://mqtt-broker:1883", "edge-proxy-main-client"); auto report_to_mqtt = [&](const UnifiedData& data) { + live_data_cache.update_data(data.device_id, data.data_json); if (mqtt_client.is_connected()) { // 网络正常,直接上报 std::string topic = "devices/" + data.device_id + "/data"; @@ -97,10 +100,9 @@ int main(int argc, char* argv[]) { device_manager.load_and_start("../config/devices.json"); - WebServer web_server(monitor, device_manager,8080); + WebServer web_server(monitor, device_manager, live_data_cache, 8080); web_server.start(); - // --- 2. <<< MODIFIED: 设置 Boost.Asio 风格的信号处理器 >>> --- boost::asio::signal_set signals(g_io_context, SIGINT, SIGTERM); signals.async_wait([&](const boost::system::error_code& error, int signal_number) { spdlog::warn("Interrupt signal ({}) received. Shutting down.", signal_number); diff --git a/src/web/web_server.cc b/src/web/web_server.cc index a1851db..5e921b7 100644 --- a/src/web/web_server.cc +++ b/src/web/web_server.cc @@ -3,9 +3,9 @@ #include "spdlog/spdlog.h" // 构造函数现在需要调用基类的构造函数 -WebServer::WebServer(SystemMonitor::SystemMonitor& monitor, DeviceManager& deviceManager, uint16_t port) +WebServer::WebServer(SystemMonitor::SystemMonitor& monitor, DeviceManager& deviceManager, LiveDataCache& liveDataCache,uint16_t port) // 注意基类已经改为 crow::Crow() - : crow::Crow(), m_monitor(monitor),m_device_manager(deviceManager), m_port(port) + : crow::Crow(), m_monitor(monitor), m_device_manager(deviceManager), m_live_data_cache(liveDataCache), m_port(port) { // ================= [ 新增 CORS 配置 ] ================= // 获取 CORS 中间件的引用 @@ -65,7 +65,6 @@ void WebServer::setup_routes() { return response; }); - // ================= [ 新增设备列表 API ] ================= CROW_ROUTE((*this), "/api/devices").methods("GET"_method) ([this] { // 这一行不变,从 DeviceManager 获取最新的设备信息 @@ -92,5 +91,22 @@ void WebServer::setup_routes() { return crow::json::wvalue(devices_json); }); - // ========================================================== + + // ================= [ 新增实时数据 API ] ================= + CROW_ROUTE((*this), "/api/data/latest").methods("GET"_method) + ([this] { + // 从缓存中获取所有设备的最新数据 + auto latest_data_map = m_live_data_cache.get_all_data(); + + crow::json::wvalue response; + for (const auto& pair : latest_data_map) { + // pair.first 是 device_id (string) + // pair.second 是 json_data (string) + // 我们需要将 json_data 字符串再次解析为 crow 的 json 对象 + response[pair.first] = crow::json::load(pair.second); + } + + return response; + }); + } \ No newline at end of file diff --git a/src/web/web_server.h b/src/web/web_server.h index 4b786cb..4cea44a 100644 --- a/src/web/web_server.h +++ b/src/web/web_server.h @@ -8,6 +8,7 @@ #include "systemMonitor/system_monitor.h" #include "deviceManager/device_manager.h" +#include "dataCache/live_data_cache.h" #include @@ -16,7 +17,11 @@ class WebServer : public crow::Crow { public: - WebServer(SystemMonitor::SystemMonitor& monitor, DeviceManager& deviceManager, uint16_t port = 8080); + WebServer(SystemMonitor::SystemMonitor& monitor, + DeviceManager& deviceManager, + LiveDataCache& liveDataCache, + uint16_t port = 8080 + ); ~WebServer(); WebServer(const WebServer&) = delete; @@ -30,6 +35,8 @@ private: SystemMonitor::SystemMonitor& m_monitor; DeviceManager& m_device_manager; + LiveDataCache& m_live_data_cache; + uint16_t m_port; std::thread m_thread;