Files
microser/cfg_parse/httprun.cpp
2025-01-16 16:17:01 +08:00

247 lines
8.6 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <thread>
#include <iostream>
#include "httplib.h"
#include <string>
#include "../json/cjson.h"
//#include <mutex>
//#include <queue>
//std::mutex data_mutex; // 用来保护 receivedData 变量
//#include <atomic>
//std::atomic<bool> isrunning(false); // 使用原子变量保证 isrunning 的内存可见性
//std::queue<std::string> receivedData; // 用于存储接收到的数据
bool isrunning = true; //用于线程同步
std::string receivedData;
//std::queue<std::string> receivedData2; // 用于存储接收到的数据
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) {
// 打印请求的查询参数
//std::cout << "Query parameters: " << std::endl;
//std::lock_guard<std::mutex> lock(data_mutex);
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){
/*if (!receivedData.empty()) {
std::string msg = receivedData.front(); // 获取队列中的第一条消息
receivedData.pop(); // 从队列中移除这条消息
return msg.c_str();
}
return "recall queue empty";*/
return receivedData.c_str();
}
if(2 == fun){
/*if (!receivedData2.empty()) {
std::string msg = receivedData2.front(); // 获取队列中的第一条消息
receivedData2.pop(); // 从队列中移除这条消息
return msg.c_str();
}
return "rtdata queue empty";*/
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() {
//std::cout << "WebhttpThread::run() is called ...... " << std::endl;
// 创建 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 方法处理请求
// 监听端口 10004
//std::cout << "Server started at http://0.0.0.0:10004" << std::endl;
if (!svr.listen(HTTP_IP, HTTP_PORT)) { // 监听所有 IP
std::cerr << "Error: Unable to start server on port 10004" << std::endl;
}
//std::cout << "WebhttpThread::run() is end ...... " << std::endl;
}