2025-01-16 16:17:01 +08:00
|
|
|
|
#include <thread>
|
|
|
|
|
|
#include <iostream>
|
|
|
|
|
|
#include "httplib.h"
|
|
|
|
|
|
#include <string>
|
|
|
|
|
|
#include "../json/cjson.h"
|
|
|
|
|
|
|
|
|
|
|
|
bool isrunning = true; //用于线程同步
|
|
|
|
|
|
std::string receivedData;
|
|
|
|
|
|
|
|
|
|
|
|
bool isrunning2 = true; //用于线程同步
|
|
|
|
|
|
std::string receivedData2;
|
|
|
|
|
|
|
|
|
|
|
|
extern std::string HTTP_IP;
|
|
|
|
|
|
extern int HTTP_PORT;
|
|
|
|
|
|
|
|
|
|
|
|
//设置回复消息体
|
|
|
|
|
|
std::string recall_success = "{\"code\":\"A0000\", \"msg\":\"数据补招执行成功\", \"data\":null}";
|
|
|
|
|
|
std::string recall_fail = "{\"code\":\"A0002\", \"msg\":\"数据补招执行失败\", \"data\":null}";
|
|
|
|
|
|
std::string rtdata_success = "{\"code\":\"A0000\", \"msg\":\"3s数据执行成功\", \"data\":null}";
|
|
|
|
|
|
std::string rtdata_fail = "{\"code\":\"A0002\", \"msg\":\"3s数据执行失败\", \"data\":null}";
|
|
|
|
|
|
|
|
|
|
|
|
// 处理补招请求的函数
|
|
|
|
|
|
std::string HandleRecall_http(const httplib::Request& req, httplib::Response& res) {
|
|
|
|
|
|
|
|
|
|
|
|
if(isrunning == true){ //收到前置信号,收到信息可以处理消息
|
|
|
|
|
|
if (req.body.empty()) { //消息体为空
|
|
|
|
|
|
|
|
|
|
|
|
std::cout << "req.body.empty" << std::endl;
|
|
|
|
|
|
|
|
|
|
|
|
res.status = 400;
|
|
|
|
|
|
res.set_content(recall_fail, "application/json");
|
|
|
|
|
|
return recall_fail;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 消息体不为空,解析 JSON 数据
|
|
|
|
|
|
cJSON* json_root = cJSON_Parse(req.body.c_str());
|
|
|
|
|
|
//解析失败或者消息体不为数组
|
|
|
|
|
|
if (json_root == NULL || json_root->type != cJSON_Array) {
|
|
|
|
|
|
|
|
|
|
|
|
std::cout << "json_root NULL or json_roottype not cJSON_Array" << std::endl;
|
|
|
|
|
|
|
|
|
|
|
|
res.status = 400;
|
|
|
|
|
|
res.set_content(recall_fail, "application/json");
|
|
|
|
|
|
cJSON_Delete(json_root);
|
|
|
|
|
|
return recall_fail;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool is_valid = true;//默认消息体正常
|
|
|
|
|
|
//检查数组每个成员
|
|
|
|
|
|
for (cJSON* item = json_root->child; item != NULL; item = item->next) {
|
|
|
|
|
|
// 检查每个对象是否包含 monitorId、dataType、timeInterval 且不为空
|
|
|
|
|
|
cJSON* monitorId = cJSON_GetObjectItem(item, "monitorId");
|
|
|
|
|
|
cJSON* dataType = cJSON_GetObjectItem(item, "dataType");
|
|
|
|
|
|
cJSON* timeInterval = cJSON_GetObjectItem(item, "timeInterval");
|
|
|
|
|
|
|
|
|
|
|
|
//调试用
|
|
|
|
|
|
std::cout << "!timeInterval" << !timeInterval << " " << (timeInterval->type != cJSON_Array) << " "<< (timeInterval->child == NULL) << std::endl;
|
|
|
|
|
|
|
|
|
|
|
|
if (!timeInterval || //元素必须不为空
|
|
|
|
|
|
timeInterval->type != cJSON_Array || timeInterval->child == NULL) { // timeInterval 必须为非空数组
|
|
|
|
|
|
is_valid = false; //不满足结构则消息体不正常
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 清理 JSON 数据
|
|
|
|
|
|
cJSON_Delete(json_root);
|
|
|
|
|
|
|
|
|
|
|
|
// 设置响应内容
|
|
|
|
|
|
if (is_valid) {
|
|
|
|
|
|
res.status = 200; //消息体正常返回补招执行成功
|
|
|
|
|
|
res.set_content(recall_success, "application/json");
|
|
|
|
|
|
|
|
|
|
|
|
receivedData = req.body; //提供给前置获取消息体处理
|
|
|
|
|
|
isrunning = false; //停止处理http收到的消息直到收到前置的信号
|
|
|
|
|
|
|
|
|
|
|
|
return recall_success;
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
|
|
|
|
std::cout << "json not right" << std::endl;
|
|
|
|
|
|
|
|
|
|
|
|
res.status = 400;
|
|
|
|
|
|
res.set_content(recall_fail, "application/json");
|
|
|
|
|
|
return recall_fail;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
return req.body; // 返回接收到的未处理的 JSON,暂时没有任何地方使用
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 处理实时数据请求的函数
|
|
|
|
|
|
std::string HandleRtdata_http(const httplib::Request& req, httplib::Response& res) {
|
|
|
|
|
|
|
|
|
|
|
|
if(isrunning2 == true){ //收到前置信号,收到信息可以处理消息
|
|
|
|
|
|
if (req.body.empty()) { //消息体为空
|
|
|
|
|
|
|
|
|
|
|
|
std::cout << "req.body.empty" << std::endl;
|
|
|
|
|
|
|
|
|
|
|
|
res.status = 400;
|
|
|
|
|
|
res.set_content(rtdata_fail, "application/json");
|
|
|
|
|
|
return rtdata_fail;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 消息体不为空,解析 JSON 数据
|
|
|
|
|
|
cJSON* json_root = cJSON_Parse(req.body.c_str());
|
|
|
|
|
|
//解析失败或者消息体不为数组
|
|
|
|
|
|
if (json_root == NULL || json_root->type != cJSON_Array) {
|
|
|
|
|
|
|
|
|
|
|
|
std::cout << "json_root NULL or json_roottype not cJSON_Array" << std::endl;
|
|
|
|
|
|
|
|
|
|
|
|
res.status = 400;
|
|
|
|
|
|
res.set_content(rtdata_fail, "application/json");
|
|
|
|
|
|
cJSON_Delete(json_root);
|
|
|
|
|
|
return rtdata_fail;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool is_valid = true;//默认消息体正常
|
|
|
|
|
|
//检查数组每个成员
|
|
|
|
|
|
for (cJSON* item = json_root->child; item != NULL; item = item->next) {
|
|
|
|
|
|
// 检查每个对象不为空
|
|
|
|
|
|
cJSON* DevSeries = cJSON_GetObjectItem(item, "DevSeries");
|
|
|
|
|
|
cJSON* Line = cJSON_GetObjectItem(item, "Line");
|
|
|
|
|
|
cJSON* RealData = cJSON_GetObjectItem(item, "RealData");
|
|
|
|
|
|
cJSON* SOEData = cJSON_GetObjectItem(item, "SOEData");
|
|
|
|
|
|
cJSON* Limit = cJSON_GetObjectItem(item, "Limit");
|
|
|
|
|
|
cJSON* Count = cJSON_GetObjectItem(item, "Count");
|
|
|
|
|
|
|
|
|
|
|
|
if (!DevSeries || !Line || !RealData || !SOEData || !Limit || !Count) {
|
|
|
|
|
|
is_valid = false; //不满足结构则消息体不正常
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 清理 JSON 数据
|
|
|
|
|
|
cJSON_Delete(json_root);
|
|
|
|
|
|
|
|
|
|
|
|
// 设置响应内容
|
|
|
|
|
|
if (is_valid) {
|
|
|
|
|
|
res.status = 200; //消息体正常返回补招执行成功
|
|
|
|
|
|
res.set_content(rtdata_success, "application/json");
|
|
|
|
|
|
|
|
|
|
|
|
receivedData2 = req.body;
|
|
|
|
|
|
isrunning2 = false; //停止处理http收到的消息直到收到前置的信号
|
|
|
|
|
|
|
|
|
|
|
|
return rtdata_success;
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
|
|
|
|
std::cout << "json not right" << std::endl;
|
|
|
|
|
|
|
|
|
|
|
|
res.status = 400;
|
|
|
|
|
|
res.set_content(rtdata_fail, "application/json");
|
|
|
|
|
|
return rtdata_fail;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
return req.body; // 返回接收到的未处理的 JSON,暂时没有任何地方使用
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//处理台账更新请求函数
|
|
|
|
|
|
std::string Handleupdate_http(const httplib::Request& req, httplib::Response& res){
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 获取接收到的字符串
|
|
|
|
|
|
//extern "C" std::string getReceivedData() {
|
|
|
|
|
|
extern "C" const char* getReceivedData(int fun) {
|
|
|
|
|
|
if(1 == fun){
|
2025-04-29 15:05:36 +08:00
|
|
|
|
|
2025-01-16 16:17:01 +08:00
|
|
|
|
return receivedData.c_str();
|
|
|
|
|
|
}
|
|
|
|
|
|
if(2 == fun){
|
2025-04-29 15:05:36 +08:00
|
|
|
|
|
2025-01-16 16:17:01 +08:00
|
|
|
|
return receivedData2.c_str();
|
|
|
|
|
|
}
|
|
|
|
|
|
return "all queue empty";
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 收取信号 1是补招,2是实时数据
|
|
|
|
|
|
extern "C" void threadmsgweb(int fun) {
|
|
|
|
|
|
if(1 == fun){
|
|
|
|
|
|
isrunning = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
if(2 == fun){
|
|
|
|
|
|
isrunning2 = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 发送信号
|
|
|
|
|
|
extern "C" bool threadmsghttp(int fun) {
|
|
|
|
|
|
if(1 == fun){
|
|
|
|
|
|
return isrunning;
|
|
|
|
|
|
}
|
|
|
|
|
|
if(2 == fun){
|
|
|
|
|
|
return isrunning2;
|
|
|
|
|
|
}
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 启动 HTTP 服务器的函数
|
|
|
|
|
|
extern "C" void httprun() {
|
|
|
|
|
|
|
|
|
|
|
|
// 创建 HTTP 服务器对象
|
|
|
|
|
|
httplib::Server svr;
|
|
|
|
|
|
|
|
|
|
|
|
// 监听路径 /powerQuality/recall,绑定处理函数
|
|
|
|
|
|
svr.Post("/powerQuality/recall", HandleRecall_http); // 使用 POST 方法处理请求
|
|
|
|
|
|
|
|
|
|
|
|
// 监听路径 /powerQuality/rtdata,绑定处理函数
|
|
|
|
|
|
svr.Post("/powerQuality/rtdata", HandleRtdata_http); // 使用 POST 方法处理请求
|
|
|
|
|
|
|
|
|
|
|
|
// 监听路径 /powerQuality/update,绑定处理函数
|
|
|
|
|
|
svr.Post("/powerQuality/update", Handleupdate_http); // 使用 POST 方法处理请求
|
|
|
|
|
|
|
|
|
|
|
|
if (!svr.listen(HTTP_IP, HTTP_PORT)) { // 监听所有 IP
|
|
|
|
|
|
std::cerr << "Error: Unable to start server on port 10004" << std::endl;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|