From 78437aee5e5c082188d71887cdcc151e0a973225 Mon Sep 17 00:00:00 2001 From: duanshengchao <519970194@qq.com> Date: Mon, 22 Dec 2025 17:48:01 +0800 Subject: [PATCH] =?UTF-8?q?feat:=E5=88=9B=E5=BB=BA=E5=AE=9E=E6=97=B6?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E6=9C=AC=E5=9C=B0=E7=BC=93=E5=AD=98=E6=A1=86?= =?UTF-8?q?=E6=9E=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/measurementDataUtils.h | 50 ++++++++++++++++++++++++++ source/measurementDataManager.cpp | 15 ++++++++ source/measurementDataUtils.cpp | 59 +++++++++++++++++++++++++++++++ 3 files changed, 124 insertions(+) diff --git a/include/measurementDataUtils.h b/include/measurementDataUtils.h index 829de15..2531a63 100644 --- a/include/measurementDataUtils.h +++ b/include/measurementDataUtils.h @@ -4,6 +4,56 @@ #include "networkCommon.h" #include #include + +struct MeasurementDataPoint +{ + qint64 timestamp; + double value; + + MeasurementDataPoint() : timestamp(0), value(0.0) + {} + MeasurementDataPoint(qint64 st, double val) : timestamp(st), value(val) + {} + + bool operator < (const MeasurementDataPoint& other) const + { + return timestamp < other.timestamp; + } + + bool operator == (const MeasurementDataPoint& other) const + { + return timestamp == other.timestamp; + } +}; + +// 用于QHash的哈希函数 +inline size_t qHash(const MeasurementDataPoint& dp, size_t seed = 0) +{ + return qHash(dp.timestamp, seed); +} + +/** + * @brief 本地数据存储 + * + * 存储接收到的实时数据,具有去除重复数据功能 + */ +class MeasurementData +{ +public: + explicit MeasurementData(const QString& id); + + int insertData(const QVector& newData); + QVector getLatestData(int count); + QVector getDataInRange(qint64 startTime, qint64 endTime); + void cleanupOldData(qint64 cutoffTime); + +private: + QString m_id; + QSet m_timestamps; //用于快速查找是否存在改时间戳的数据 + QMap m_data; //按时间戳对数据点进行排序 + qint64 m_latestTimestamp; +}; + /** * @brief WebSocket数据客户端 * diff --git a/source/measurementDataManager.cpp b/source/measurementDataManager.cpp index a89f3f1..23e24cc 100644 --- a/source/measurementDataManager.cpp +++ b/source/measurementDataManager.cpp @@ -146,7 +146,10 @@ void MeasurementDataManager::processSubscriptionResponse(const QString& action, { QJsonObject payloadObj = payloadValue.toObject(); if(action == "start") + { m_clientID = payloadObj.value("client_id").toString(); + getSubscriptionRealtimeData(); + } QJsonValue targetsValue = payloadObj.value("targets"); if(targetsValue.isArray()) { @@ -208,7 +211,19 @@ void MeasurementDataManager::processSubscriptionResponse(const QString& action, void MeasurementDataManager::getSubscriptionRealtimeData() { + if(m_clientID.isEmpty()) + return; + QString strUrl = QString("ws:://%1:%2/%3/%4").arg(m_serviceConfig.realtimeCfg.host + , QString::number(m_serviceConfig.realtimeCfg.port) + , m_serviceConfig.realtimeCfg.websocketPath + , m_clientID); + QUrl url(strUrl); + if(!m_webSocketClient->connectToServer(url)) + { + QString errorMsg = QString("Connect to WebSocketServer failed."); + LOG_ERROR("WebSocket", errorMsg); + } } void MeasurementDataManager::onReciveRealtimeData(const QString& dataMsg) diff --git a/source/measurementDataUtils.cpp b/source/measurementDataUtils.cpp index bc3862f..81dbd07 100644 --- a/source/measurementDataUtils.cpp +++ b/source/measurementDataUtils.cpp @@ -3,6 +3,65 @@ #include #include +MeasurementData::MeasurementData(const QString&id) + : m_id(id) +{} + +int MeasurementData::insertData(const QVector& newData) +{ + int insertedCount = 0; + + for(const auto& point : newData) + { + if (point.timestamp > m_latestTimestamp && !m_timestamps.contains(point.timestamp)) + { + + m_timestamps.insert(point.timestamp); + m_data.insert(point.timestamp, point.value); + insertedCount++; + + m_latestTimestamp = point.timestamp; + } + } + + return insertedCount; +} + +QVector MeasurementData::getLatestData(int count) +{ + QVector result; + + auto it = m_data.constEnd(); + while(it != m_data.constBegin() && result.size() < count) + { + --it; + result.append(MeasurementDataPoint(it.key(), it.value())); + } + + return result; +} + +QVector MeasurementData::getDataInRange(qint64 startTime, qint64 endTime) +{ + QVector result; + + auto end = m_data.upperBound(endTime); + for(auto it = m_data.lowerBound(startTime); it != end; ++it) + result.append(MeasurementDataPoint(it.key(), it.value())); + + return result; +} + +void MeasurementData::cleanupOldData(qint64 cutoffTime) +{ + auto it = m_data.begin(); + while(it != m_data.end() && it.key() < cutoffTime) + { + m_timestamps.remove(it.key()); + it = m_data.erase(it); + } +} + WebSocketClient::WebSocketClient(QObject* parent) : QObject(parent) , m_webSocket(nullptr)