From 9c3326eedad516cd02ad37cb55ff972d020c8673 Mon Sep 17 00:00:00 2001 From: jinchao <383321154@qq.com> Date: Wed, 18 Jun 2025 17:13:19 +0800 Subject: [PATCH] =?UTF-8?q?V0.28.2.250618=5Falpha:=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E4=BA=86=E8=BF=90=E8=A1=8C=E4=BB=BF=E7=9C=9F=E7=AC=AC=E4=BA=8C?= =?UTF-8?q?=E6=AC=A1=E4=BC=9A=E5=AF=BC=E8=87=B4=E5=B4=A9=E6=BA=83=E7=9A=84?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Release/database/XNSim.db | Bin 1224704 -> 1224704 bytes XNMonitorServer/SystemControl.cpp | 8 +- XNMonitorServer/SystemControl.h | 2 + XNMonitorServer/TopicManager.h | 2 - XNMonitorServer/XNMonitorInterface.cpp | 106 +++++++--- XNSimHtml/components/network-monitor.js | 261 +++++++++++++++++++++++- 6 files changed, 341 insertions(+), 38 deletions(-) diff --git a/Release/database/XNSim.db b/Release/database/XNSim.db index 37e63c7365c9dff357690987b151e53772c8b91e..be98c4571a7776e22d56b585144832aecde0cf58 100644 GIT binary patch delta 416 zcmZp8;MMTJYl1Z6gNZWEj1L+US`!$zCNM2o&%wlJ&A`viXT6zGK%cL^(btPpQc+yC zvN2WMK+niR&&bHY$W+(BOxMsNF{dCS(a_w=(8$Wr?8*LhPnYyQ+12)9|AZF{d!Fpx z|9sB;=WEtH+12xG&B7;pW<6cM=SBOLr(0G&+tvJhR?Exj>s~IJK}c61c5UzX^gLbH z^K@DZ&^~8v?WYs^p08g2bj}KhtuGrIp0@9LHhmk=nrAy&pHFCeHo5o7-Z_aWxtV#} zx%V^uG+_4Pxig*p15+gv&zXsl5g`y_U9X9+T?Ynrk@7Po;=T| zvwvW!+}`woDT-%e0PplWf0#J8fB3^xA;jEtNn!dKK4wdGQv*X|BXctY3v)}oocwen z10z#i12bJi^AH1LD^p7=BSSq)1M{fqh1|^Y(`C7tx!S+*GXpUT5VHa?8xXStF$WNH e0x?LQ8;E&;m=}oofS4bM1%Oy^`xky8o&^BT{6i@K diff --git a/XNMonitorServer/SystemControl.cpp b/XNMonitorServer/SystemControl.cpp index 7722d6b..3f354ea 100644 --- a/XNMonitorServer/SystemControl.cpp +++ b/XNMonitorServer/SystemControl.cpp @@ -3,7 +3,13 @@ SystemControl::~SystemControl() { - //注销引擎控制发布者 + if (m_EngineControlWriter != nullptr) { + cleanup(); + } +} + +void SystemControl::cleanup() +{ TopicManager::Instance()->unregisterPublisher("XNSim::XNSimControl::XNRuntimeControl"); m_EngineControlWriter = nullptr; } diff --git a/XNMonitorServer/SystemControl.h b/XNMonitorServer/SystemControl.h index 0694d43..3f4b176 100644 --- a/XNMonitorServer/SystemControl.h +++ b/XNMonitorServer/SystemControl.h @@ -17,6 +17,8 @@ public: void Resume(); void Stop(); + void cleanup(); + private: XNDataWriter *m_EngineControlWriter; }; diff --git a/XNMonitorServer/TopicManager.h b/XNMonitorServer/TopicManager.h index 5119c8c..3e3cf81 100755 --- a/XNMonitorServer/TopicManager.h +++ b/XNMonitorServer/TopicManager.h @@ -56,8 +56,6 @@ public: ->delete_participant(instance->m_Participant); // 删除参与者 instance->m_Participant = nullptr; // 设置参与者为空 } - delete instance; // 删除单例 - instance = nullptr; // 设置单例为空 } } diff --git a/XNMonitorServer/XNMonitorInterface.cpp b/XNMonitorServer/XNMonitorInterface.cpp index d6e111e..cdc8c13 100644 --- a/XNMonitorServer/XNMonitorInterface.cpp +++ b/XNMonitorServer/XNMonitorInterface.cpp @@ -21,6 +21,7 @@ bool g_modelInfoMonitorStarted = false; SystemControl *systemControl = nullptr; bool g_systemControlStarted = false; +std::unordered_map g_dataInjectThreads; CSVDataInjectThread *g_csvDataInjectThread = nullptr; DataCollect *g_dataCollect = nullptr; @@ -277,24 +278,6 @@ void XN_StopMonitorModelInfo() } } -// 清理函数实现 -void XN_Cleanup() -{ - if (g_initialized) { - // 停止并清理系统信息监控 - if (g_systemInfoMonitorStarted) { - XN_StopMonitorSystemInfo(); - } - // 停止并清理模型信息监控 - if (g_modelInfoMonitorStarted) { - XN_StopMonitorModelInfo(); - } - // 清理DDS参与者 - TopicManager::cleanupParticipant(); - g_initialized = false; - } -} - int XN_InitializeEngineControl(char *errorMsg, int errorMsgSize) { if (g_systemControlStarted) { @@ -360,6 +343,16 @@ void XN_StopEngine(char *errorMsg, int errorMsgSize) systemControl->Stop(); } +void XN_CleanupEngineControl() +{ + if (g_systemControlStarted) { + systemControl->cleanup(); + delete systemControl; + systemControl = nullptr; + g_systemControlStarted = false; + } +} + int XN_StartDataMonitor(const char *structName, const int structNameLen, char *errorMsg, int errorMsgSize) { @@ -517,8 +510,6 @@ int XN_InjectDataInterface(const char *structName, const int structNameLen, return 0; } -std::unordered_map g_dataInjectThreads; - int XN_StartInjectContinuous(const char *structName, const int structNameLen, const char *interfaceNameAndData, const int interfaceNameAndDataLen, double frequency, char *infoMsg, int infoMsgSize) @@ -585,12 +576,21 @@ int XN_StopInjectContinuous(const char *structName, const int structNameLen, cha return 0; } +void XN_CleanupInjectContinuous() +{ + for (auto &it : g_dataInjectThreads) { + if (it.second) { + it.second->stop(); + it.second.reset(); + it.second = nullptr; + } + } + g_dataInjectThreads.clear(); +} // 从csv文件中注入数据接口 -int XNMONITORSERVER_EXPORT XN_InjectDataInterfaceFromCsv(const char *injectDataInfo, - const int injectDataInfoLen, - const char *csvFilePath, - const int csvFilePathLen, char *infoMsg, - int infoMsgSize) +int XN_InjectDataInterfaceFromCsv(const char *injectDataInfo, const int injectDataInfoLen, + const char *csvFilePath, const int csvFilePathLen, char *infoMsg, + int infoMsgSize) { if (!g_initialized) { if (infoMsg && infoMsgSize > 0) { @@ -724,10 +724,17 @@ int XN_StopCsvDataInject(char *infoMsg, int infoMsgSize) return 0; } -int XNMONITORSERVER_EXPORT XN_StartCollectData(const char *CollectDataInfo, - const int CollectDataInfoLen, - const char *dcsFilePath, const int dcsFilePathLen, - char *infoMsg, int infoMsgSize) +void XN_CleanupCsvDataInject() +{ + if (g_csvDataInjectThread != nullptr) { + g_csvDataInjectThread->stop(); + delete g_csvDataInjectThread; + g_csvDataInjectThread = nullptr; + } +} +int XN_StartCollectData(const char *CollectDataInfo, const int CollectDataInfoLen, + const char *dcsFilePath, const int dcsFilePathLen, char *infoMsg, + int infoMsgSize) { if (!g_initialized) { if (infoMsg && infoMsgSize > 0) { @@ -807,7 +814,7 @@ int XNMONITORSERVER_EXPORT XN_StartCollectData(const char *CollectDataInfo, return 0; } -int XNMONITORSERVER_EXPORT XN_GetCollectDataStatus(char *infoMsg, int infoMsgSize) +int XN_GetCollectDataStatus(char *infoMsg, int infoMsgSize) { if (!g_initialized) { if (infoMsg && infoMsgSize > 0) { @@ -828,7 +835,7 @@ int XNMONITORSERVER_EXPORT XN_GetCollectDataStatus(char *infoMsg, int infoMsgSiz return g_dataCollect->isRunning() ? 1 : 0; } -int XNMONITORSERVER_EXPORT XN_StopCollectData(char *infoMsg, int infoMsgSize) +int XN_StopCollectData(char *infoMsg, int infoMsgSize) { if (!g_initialized) { if (infoMsg && infoMsgSize > 0) { @@ -859,4 +866,41 @@ int XNMONITORSERVER_EXPORT XN_StopCollectData(char *infoMsg, int infoMsgSize) } return 0; +} + +void XN_CleanupDataCollect() +{ + if (g_dataCollect != nullptr) { + g_dataCollect->stop(); + delete g_dataCollect; + g_dataCollect = nullptr; + } +} +// 清理函数实现 +void XN_Cleanup() +{ + if (g_initialized) { + // 停止并清理系统信息监控 + if (g_systemInfoMonitorStarted) { + XN_StopMonitorSystemInfo(); + } + // 停止并清理模型信息监控 + if (g_modelInfoMonitorStarted) { + XN_StopMonitorModelInfo(); + } + // 停止并清理引擎控制 + if (g_systemControlStarted) { + XN_CleanupEngineControl(); + } + // 停止并清理数据采集 + XN_CleanupDataCollect(); + // 停止并清理CSV数据注入 + XN_CleanupCsvDataInject(); + // 停止并清理数据注入 + XN_CleanupInjectContinuous(); + + // 清理DDS参与者 + TopicManager::cleanupParticipant(); + g_initialized = false; + } } \ No newline at end of file diff --git a/XNSimHtml/components/network-monitor.js b/XNSimHtml/components/network-monitor.js index 6725373..7f33b15 100644 --- a/XNSimHtml/components/network-monitor.js +++ b/XNSimHtml/components/network-monitor.js @@ -1,11 +1,19 @@ /** * @class NetworkMonitor - * @description 网络监控组件,用于监控系统网络状态 + * @description 网络监控组件,用于监控系统网络状态和UDP数据抓包 */ class NetworkMonitor extends HTMLElement { constructor() { super(); this.attachShadow({ mode: 'open' }); + this.state = { + ip: '127.0.0.1', + port: 54321, + isMonitoring: false, + data: [], + timer: null, + statusMsg: '', + }; } connectedCallback() { @@ -13,23 +21,268 @@ class NetworkMonitor extends HTMLElement { this.initialize(); } + disconnectedCallback() { + if (this.state.timer) { + clearInterval(this.state.timer); + } + } + render() { this.shadowRoot.innerHTML = ` -
+
${this.state.statusMsg}
+
+ + + + +
+
抓包状态:${this.state.isMonitoring ? '运行中' : '已停止'}
+
`; + this.shadowRoot.getElementById('startBtn').onclick = () => this.startMonitor(); + this.shadowRoot.getElementById('stopBtn').onclick = () => this.stopMonitor(); + this.shadowRoot.getElementById('ip').onchange = (e) => { + this.state.ip = e.target.value; + }; + this.shadowRoot.getElementById('port').onchange = (e) => { + this.state.port = parseInt(e.target.value, 10); + }; + this.renderDataList(); + } + + renderDataList() { + const dataList = this.shadowRoot.getElementById('dataList'); + if (!dataList) return; + if (!this.state.data.length) { + dataList.innerHTML = '
暂无数据
'; + return; + } + dataList.innerHTML = this.state.data.map(item => ` +
+
时间: ${new Date(item.timestamp).toLocaleString()}
+
来源: ${item.source}
+
内容:
${typeof item.data === 'object' ? JSON.stringify(item.data, null, 2) : item.data}
+
+ `).join(''); + } + + setStatus(msg) { + this.state.statusMsg = msg; + this.render(); + } + + async startMonitor() { + this.setStatus('正在启动UDP抓包...'); + try { + const res = await fetch('/api/udp-monitor/start', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ ip: this.state.ip, port: this.state.port }) + }); + const data = await res.json(); + if (data.success) { + this.state.isMonitoring = true; + this.setStatus(data.message || 'UDP抓包已启动'); + this.startPolling(); + } else { + this.state.isMonitoring = false; + this.setStatus(data.error || '启动失败'); + } + } catch (e) { + this.state.isMonitoring = false; + this.setStatus('启动UDP抓包失败: ' + e.message); + } + this.render(); + } + + async stopMonitor() { + this.setStatus('正在停止UDP抓包...'); + try { + const res = await fetch('/api/udp-monitor/stop', { method: 'POST' }); + const data = await res.json(); + this.state.isMonitoring = false; + this.setStatus(data.message || 'UDP抓包已停止'); + if (this.state.timer) { + clearInterval(this.state.timer); + this.state.timer = null; + } + } catch (e) { + this.setStatus('停止UDP抓包失败: ' + e.message); + } + this.render(); + } + + startPolling() { + if (this.state.timer) clearInterval(this.state.timer); + this.state.timer = setInterval(() => this.fetchData(), 1000); + } + + async fetchData() { + if (!this.state.isMonitoring) return; + try { + const res = await fetch('/api/udp-monitor/data'); + const data = await res.json(); + if (data.success) { + if (Array.isArray(data.data) && data.data.length > 0) { + this.state.data = this.state.data.concat(data.data); + // 最多只保留1000条 + if (this.state.data.length > 1000) { + this.state.data = this.state.data.slice(-1000); + } + this.renderDataList(); + } + this.state.isMonitoring = data.isMonitoring; + this.shadowRoot.getElementById('monitorStatus').textContent = data.isMonitoring ? '运行中' : '已停止'; + } + } catch (e) { + this.setStatus('获取UDP数据失败: ' + e.message); + } } initialize() { - console.log('网络监控组件已初始化'); + this.setStatus('请设置IP和端口后点击开始抓包'); + // 检查当前监控状态 + fetch('/api/udp-monitor/status').then(res => res.json()).then(data => { + if (data.success && data.isMonitoring) { + this.state.isMonitoring = true; + this.state.ip = data.ip || this.state.ip; + this.state.port = data.port || this.state.port; + this.setStatus('UDP抓包已在运行'); + this.startPolling(); + this.render(); + } + }); } reactivate() { - console.log('网络监控组件已重新激活'); + this.initialize(); } }