XNSim/XNSimPortal/routes/DataMonitor.js

422 lines
14 KiB
JavaScript
Raw Permalink Normal View History

const express = require('express');
const router = express.Router();
const systemMonitor = require('../utils/xnCoreService');
// 存储连续注入状态
const continuousInjectStatus = new Map();
/**
* @brief 启动数据监控
* @route POST /api/data-monitor/start
* @param {string} structName - 结构体名称
* @returns {Object} 返回启动结果
*/
router.post('/start', async (req, res) => {
try {
const { structName } = req.body;
if (!structName) {
return res.status(400).json({ success: false, message: '结构体名称不能为空' });
}
const result = systemMonitor.startDataMonitor(structName);
if (result.includes('失败')) {
return res.status(500).json({ success: false, message: result });
}
res.json({ success: true, message: result });
} catch (error) {
res.status(500).json({ success: false, message: `启动数据监控失败: ${error.message}` });
}
});
/**
* @brief 停止数据监控
* @route POST /api/data-monitor/stop
* @param {string} structName - 结构体名称
* @returns {Object} 返回停止结果
*/
router.post('/stop', async (req, res) => {
try {
const { structName } = req.body;
if (!structName) {
return res.status(400).json({ success: false, message: '结构体名称不能为空' });
}
const result = systemMonitor.stopDataMonitor(structName);
if (result.includes('失败')) {
return res.status(500).json({ success: false, message: result });
}
res.json({ success: true, message: result });
} catch (error) {
res.status(500).json({ success: false, message: `停止数据监控失败: ${error.message}` });
}
});
/**
* @brief 获取数据监控信息
* @route GET /api/data-monitor/info
* @param {string} structName - 结构体名称
* @param {string} interfaceName - 接口名称
* @param {number} [bufferSize=8192] - 数据缓冲区大小可选
* @returns {Object} 返回监控信息data字段包含解析后的JSON对象
*/
router.get('/info', async (req, res) => {
try {
const { structName, interfaceName, bufferSize } = req.query;
if (!structName || !interfaceName) {
return res.status(400).json({
success: false,
message: '结构体名称和接口名称不能为空'
});
}
const result = systemMonitor.getDataMonitorInfo(
structName,
interfaceName,
bufferSize ? parseInt(bufferSize) : undefined
);
if (typeof result === 'string' && result.includes('失败')) {
return res.status(500).json({ success: false, message: result });
}
// 解析数据字符串为JSON对象
let parsedData;
try {
parsedData = JSON.parse(result.data);
} catch (parseError) {
return res.status(500).json({
success: false,
message: `数据解析失败: ${parseError.message}`
});
}
res.json({
success: true,
data: parsedData,
info: result.info
});
} catch (error) {
res.status(500).json({ success: false, message: `获取数据监控信息失败: ${error.message}` });
}
});
/**
* @brief 注入数据接口
* @route POST /api/data-monitor/inject
* @param {string} structName - 结构体名称
* @param {string} interfaceNameAndData - 接口名称和数据JSON字符串
* @returns {Object} 返回注入结果
*/
router.post('/inject', async (req, res) => {
try {
const { structName, interfaceNameAndData } = req.body;
if (!structName || !interfaceNameAndData) {
return res.status(400).json({
success: false,
message: '结构体名称和接口数据不能为空'
});
}
const result = systemMonitor.injectDataInterface(structName, interfaceNameAndData);
if (result.includes('失败')) {
return res.status(500).json({ success: false, message: result });
}
res.json({ success: true, message: result });
} catch (error) {
res.status(500).json({ success: false, message: `注入数据接口失败: ${error.message}` });
}
});
/**
* @brief 启动持续注入数据
* @route POST /api/data-monitor/start-continuous
* @param {string} structName - 结构体名称
* @param {string} interfaceNameAndData - 接口名称和数据JSON字符串
* @param {number} frequency - 注入频率
* @returns {Object} 返回启动结果
*/
router.post('/start-continuous', async (req, res) => {
try {
const { structName, interfaceNameAndData, frequency } = req.body;
if (!structName || !interfaceNameAndData || frequency === undefined) {
return res.status(400).json({
success: false,
message: '结构体名称、接口数据和注入频率不能为空'
});
}
// 检查是否已存在该结构体的注入状态
if (continuousInjectStatus.has(structName)) {
const status = continuousInjectStatus.get(structName);
// 检查频率是否相同
if (status.frequency !== frequency) {
return res.status(400).json({
success: false,
message: `该结构体已有其他接口以 ${status.frequency}ms 的频率进行注入,请使用相同的频率`
});
}
// 合并接口数据
try {
const existingData = JSON.parse(status.interfaceNameAndData);
const newData = JSON.parse(interfaceNameAndData);
const mergedData = { ...existingData, ...newData };
status.interfaceNameAndData = JSON.stringify(mergedData);
} catch (error) {
return res.status(400).json({
success: false,
message: '接口数据格式错误'
});
}
// 启动注入
const result = systemMonitor.startInjectContinuous(structName, status.interfaceNameAndData, frequency);
if (result.includes('失败')) {
continuousInjectStatus.delete(structName);
return res.status(500).json({ success: false, message: result });
}
} else {
// 创建新的注入状态
continuousInjectStatus.set(structName, {
interfaceNameAndData,
frequency,
isInjecting: false
});
// 启动注入
const result = systemMonitor.startInjectContinuous(structName, interfaceNameAndData, frequency);
if (result.includes('失败')) {
continuousInjectStatus.delete(structName);
return res.status(500).json({ success: false, message: result });
}
// 更新注入状态
const status = continuousInjectStatus.get(structName);
status.isInjecting = true;
}
res.json({
success: true,
message: '启动持续注入成功',
data: {
structName,
interfaceNameAndData: continuousInjectStatus.get(structName).interfaceNameAndData,
frequency
}
});
} catch (error) {
res.status(500).json({ success: false, message: `启动持续注入数据失败: ${error.message}` });
}
});
/**
* @brief 停止持续注入数据
* @route POST /api/data-monitor/stop-continuous
* @param {string} structName - 结构体名称
* @param {string} interfaceName - 要停止的接口名称
* @returns {Object} 返回停止结果
*/
router.post('/stop-continuous', async (req, res) => {
try {
const { structName, interfaceName } = req.body;
if (!structName || !interfaceName) {
return res.status(400).json({
success: false,
message: '结构体名称和接口名称不能为空'
});
}
// 检查是否存在该结构体的注入状态
if (!continuousInjectStatus.has(structName)) {
return res.status(400).json({
success: false,
message: '该结构体没有正在进行的注入'
});
}
const status = continuousInjectStatus.get(structName);
try {
// 从接口数据中移除指定的接口
const existingData = JSON.parse(status.interfaceNameAndData);
delete existingData[interfaceName];
// 如果还有其他接口在注入,更新状态
if (Object.keys(existingData).length > 0) {
status.interfaceNameAndData = JSON.stringify(existingData);
const result = systemMonitor.startInjectContinuous(structName, status.interfaceNameAndData, status.frequency);
if (result.includes('失败')) {
return res.status(500).json({ success: false, message: result });
}
res.json({
success: true,
message: '停止指定接口的注入成功',
data: {
structName,
remainingInterfaces: Object.keys(existingData)
}
});
} else {
// 如果没有其他接口在注入,停止整个结构体的注入
const result = systemMonitor.stopInjectContinuous(structName);
if (result.includes('失败')) {
return res.status(500).json({ success: false, message: result });
}
// 删除注入状态
continuousInjectStatus.delete(structName);
res.json({
success: true,
message: '停止所有接口的注入成功'
});
}
} catch (error) {
return res.status(400).json({
success: false,
message: '接口数据格式错误'
});
}
} catch (error) {
res.status(500).json({ success: false, message: `停止持续注入数据失败: ${error.message}` });
}
});
/**
* @brief 停止所有持续注入数据
* @route POST /api/data-monitor/stop-all-continuous
* @returns {Object} 返回停止结果
*/
router.post('/stop-all-continuous', async (req, res) => {
try {
// 获取所有正在注入的结构体
const injectingStructs = Array.from(continuousInjectStatus.keys());
if (injectingStructs.length === 0) {
return res.json({
success: true,
message: '当前没有正在进行的注入'
});
}
// 停止所有结构体的注入
const results = [];
for (const structName of injectingStructs) {
const result = systemMonitor.stopInjectContinuous(structName);
if (result.includes('失败')) {
results.push({ structName, success: false, message: result });
} else {
results.push({ structName, success: true, message: '停止成功' });
}
continuousInjectStatus.delete(structName);
}
// 检查是否所有结构体都成功停止
const allSuccess = results.every(r => r.success);
res.json({
success: allSuccess,
message: allSuccess ? '所有持续注入已停止' : '部分持续注入停止失败',
details: results
});
} catch (error) {
res.status(500).json({ success: false, message: `停止所有持续注入数据失败: ${error.message}` });
}
});
/**
* @brief 从CSV文件注入数据
* @route POST /api/data-monitor/inject-csv
* @param {string} structName - 结构体数据JSON字符串格式为 {structName1: {interfaceName1: [size1, size2], ...}, structName2: ...}
* @param {string} csvFilePath - CSV文件路径
* @returns {Object} 返回注入结果
*/
router.post('/inject-csv', async (req, res) => {
try {
const { structName, csvFilePath} = req.body;
if (!structName || !csvFilePath) {
return res.status(400).json({
success: false,
message: '结构体名称、CSV文件路径不能为空'
});
}
// 解析并验证 structName JSON 字符串
let structData;
try {
structData = JSON.parse(structName);
// 验证数据结构
if (typeof structData !== 'object' || structData === null) {
return res.status(400).json({
success: false,
message: '结构体数据格式错误:必须是有效的对象'
});
}
// 验证每个结构体的接口数据
for (const [structName, interfaces] of Object.entries(structData)) {
if (typeof interfaces !== 'object' || interfaces === null) {
return res.status(400).json({
success: false,
message: `结构体 ${structName} 的接口数据格式错误:必须是有效的对象`
});
}
for (const [interfaceName, sizes] of Object.entries(interfaces)) {
if (!Array.isArray(sizes) || sizes.length !== 2 ||
typeof sizes[0] !== 'number' || typeof sizes[1] !== 'number' ||
sizes[0] < 0 || sizes[1] < 0) {
return res.status(400).json({
success: false,
message: `接口 ${interfaceName} 的数据格式错误:必须是包含两个非负数字的数组 [size1, size2]`
});
}
}
}
} catch (error) {
return res.status(400).json({
success: false,
message: `结构体数据解析失败: ${error.message}`
});
}
const result = systemMonitor.injectDataInterfaceFromCsv(structName, csvFilePath);
if (result.includes('失败')) {
return res.status(500).json({ success: false, message: result });
}
res.json({ success: true, message: result });
} catch (error) {
res.status(500).json({ success: false, message: `从CSV文件注入数据失败: ${error.message}` });
}
});
/**
* @brief 停止CSV数据注入
* @route POST /api/data-monitor/stop-csv-inject
* @returns {Object} 返回停止结果
*/
router.post('/stop-csv-inject', async (req, res) => {
try {
const result = systemMonitor.stopCsvDataInject();
if (result.includes('失败')) {
return res.status(500).json({ success: false, message: result });
}
res.json({ success: true, message: result });
} catch (error) {
res.status(500).json({ success: false, message: `停止CSV数据注入失败: ${error.message}` });
}
});
/**
* @brief 获取CSV数据注入状态
* @route GET /api/data-monitor/csv-inject-status
* @returns {Object} 返回CSV数据注入状态
*/
router.get('/csv-inject-status', async (req, res) => {
try {
const result = systemMonitor.getCsvDataInjectStatus();
res.json({ success: true, data: result });
} catch (error) {
res.status(500).json({ success: false, message: `获取CSV数据注入状态失败: ${error.message}` });
}
});
module.exports = router;