应急联调完成

This commit is contained in:
zjk
2025-05-19 20:42:20 +08:00
parent baa2e395fa
commit fea319d3bf
35 changed files with 1188 additions and 558 deletions
@@ -8,6 +8,7 @@
#include <sys/resource.h>
#include "data.h"
#include "logpage.h"
#include "testpage.h"
using json = Json::Value;
@@ -76,6 +77,15 @@ void HttpServer::handleWebSocketEvent(struct mg_connection* c, int ev, void* ev_
} else if (mg_match(hm->uri, mg_str("/logs"), NULL)) {
// 返回日志页面HTML
mg_http_reply(c, 200, "Content-Type: text/html; charset=utf-8\r\n", LOG_PAGE_HTML.c_str());
} else if (mg_match(hm->uri, mg_str("/testpage"), NULL)) {
if (mg_strcmp(hm->method, mg_str("POST")) == 0) {
// 解析POST请求并调用处理函数
std::string msg(hm->body.buf, hm->body.len);
handleTestPage(c, msg);
} else {
// 返回测试页面HTML
mg_http_reply(c, 200, "Content-Type: text/html; charset=utf-8\r\n", TESTPAGE_HTML.c_str());
}
} else if (mg_match(hm->uri, mg_str("/control"), NULL)) {
// 处理断路器控制请求
if (mg_strcmp(hm->method, mg_str("POST")) == 0) {
@@ -655,6 +665,84 @@ std::vector<std::string> HttpServer::readLogFile(int page, int pageSize, const s
return std::vector<std::string>(filteredLogs.begin() + start, filteredLogs.begin() + end);
}
void HttpServer::handleTestPage(struct mg_connection* c, const std::string& msg) {
try {
// 检查空消息
if (msg.empty()) {
LOG_F(ERROR, "Empty test page request received");
mg_http_reply(c, 400, "Content-Type: application/json\r\n",
"{\"success\": false, \"error\": \"Empty request body\"}");
return;
}
// 解析JSON请求
Json::Value json;
Json::CharReaderBuilder builder;
std::unique_ptr<Json::CharReader> reader(builder.newCharReader());
std::string errors;
const char* msg_start = msg.c_str();
const char* msg_end = msg_start + msg.size();
if (!reader->parse(msg_start, msg_end, &json, &errors)) {
// 记录详细的解析错误
LOG_F(ERROR, "Failed to parse test page request JSON: %s\nRequest content: %s",
errors.c_str(), msg.c_str());
// 返回结构化的错误响应
mg_http_reply(c, 400, "Content-Type: application/json\r\n",
"{\"success\": false, \"error\": \"Invalid JSON format\", "
"\"details\": \"%s\", \"position\": %d}",
errors.c_str(), (int)(errors.find("offset") != std::string::npos ?
std::stoi(errors.substr(errors.find("offset") + 7)) : 0));
return;
}
// 记录接收到的请求
LOG_F(INFO, "Received valid test page request: %s", msg.c_str());
// 检查必需字段是否存在
if (!json.isMember("type") || !json.isMember("id")) {
mg_http_reply(c, 400, "Content-Type: application/json\r\n",
"{\"success\": false, \"error\": \"type and id fields are required\"}");
return;
}
unsigned int type = 0;
unsigned int id = 0;
try {
if (json["type"].isString()) {
type = std::stoul(json["type"].asString());
} else if (json["type"].isNumeric()) {
type = json["type"].asUInt();
} else {
throw std::invalid_argument("type must be number or numeric string");
}
if (json["id"].isString()) {
id = std::stoul(json["id"].asString());
} else if (json["id"].isNumeric()) {
id = json["id"].asUInt();
} else {
throw std::invalid_argument("id must be number or numeric string");
}
} catch (const std::exception& e) {
mg_http_reply(c, 400, "Content-Type: application/json\r\n",
"{\"success\": false, \"error\": \"%s\"}", e.what());
return;
}
m_powerManger->injectFault(type, id);
// 返回成功响应
mg_http_reply(c, 200, "Content-Type: application/json\r\n",
"{\"success\": true, \"message\": \"Request received\", "
"\"content\": %s}",
msg.c_str());
} catch (const std::exception& e) {
LOG_F(ERROR, "Error handling test page request: %s", e.what());
mg_http_reply(c, 500, "Content-Type: text/plain\r\n", "Internal server error");
}
}
void HttpServer::monitorLogFile() {
static std::streampos lastPos = 0;
std::ifstream file(m_logFilePath);