Files
ECAP_Server/module/Local_Server/server/Global.h
T
2026-06-25 11:17:52 +08:00

301 lines
9.7 KiB
C++

#pragma once
#include "Core/Base/ThreadManager.h"
#include "../Data_Source/export.h"
#include "../State_Report/State_Report.h"
#include "../global_include.h"
#include "Ucoro_Drogon_Glue.h"
#include "Config.h"
#include <drogon/drogon.h>
#include "Config.h"
#include "../../Radarcape_Core/cpp-httplib/httplib.h"
#include "../Data_Source/export.h"
#include "Core/Net_Adapter/Net_Adapter.h"
#include "libarchive.h"
#include <filesystem>
#include <list>
#include <utility>
// 集中 管理日志
using namespace Psc;
extern BaseLogger* server_logger;
std::string to_file_name(std::string str);
std::string inet_address_to_string(const trantor::InetAddress &addr);
using Serial_Number_Type = unsigned int;
struct Debug_Logger_Info_Manager {
void push_info(const std::string& content);
std::string get_info(Serial_Number_Type serial_number);
Serial_Number_Type get_cur_serial_number();
struct Info {
Serial_Number_Type sequence;
std::string content;
};
std::list<Info> info_list;
JSON to_json();
private:
// 最大总长度
static constexpr size_t max_length = 1000 * 300;
// 当前总长度
size_t current_total_length = 0;
Serial_Number_Type cur_serial_number = 0;
std::mutex mtx;
};
extern Debug_Logger_Info_Manager debug_logger_info_manager;
#define RET_OK \
res.status = StatusCode::OK_200; \
res.set_content("{\"status\": 200}", "application/json");
inline JSON warp(const JSON& data) {
// Json ret = Json::object();
// ret.append({"status", 200});
// ret.append({"data", data});
// return ret;
return data;
}
#define HTTP_Param const drogon::HttpRequestPtr& req, const drogon::HttpResponsePtr& res
class Web_Server {
public:
std::string update = "update_";
std::string insert = "insert_";
std::string remove = "remove_";
std::string search = "search_";
std::string rise = "rise_";
std::string fall = "fall_";
using Handler = std::function<void(const drogon::HttpRequestPtr&, const drogon::HttpResponsePtr&)>;
using CoroHandler = std::function<drogon::Task<>(const drogon::HttpRequestPtr&, const drogon::HttpResponsePtr&)>;
bool listen(const std::string& host, int port);
~Web_Server() = default;
static void stop() {
std::cout << "开始停止web服务" << std::endl;
drogon::app().quit();
}
Web_Server& Post(const std::string& pattern, Handler handler) {
drogon::app().registerHandler(
pattern,
[handler](const drogon::HttpRequestPtr& request,
std::function<void(const drogon::HttpResponsePtr&)>&& callback) {
auto resp = drogon::HttpResponse::newHttpResponse();
resp->setContentTypeCode(drogon::CT_APPLICATION_JSON);
handler(request, resp);
callback(resp);
},
{drogon::Post}
);
return *this;
}
Web_Server& PostCoro(const std::string& pattern, CoroHandler handler) {
drogon::app().registerHandler(
pattern,
[handler = std::move(handler)](
const drogon::HttpRequestPtr& request,
std::function<void(const drogon::HttpResponsePtr&)>&& callback) {
auto resp = drogon::HttpResponse::newHttpResponse();
resp->setContentTypeCode(drogon::CT_APPLICATION_JSON);
drogon::async_run(
[handler, request, resp, callback = std::move(callback)]() mutable -> drogon::Task<> {
try {
co_await handler(request, resp);
} catch (const std::exception& error) {
resp->setStatusCode(drogon::k500InternalServerError);
resp->setBody(Psc::JSON::object({{"error", std::string(error.what())}}).to_json_string());
} catch (...) {
resp->setStatusCode(drogon::k500InternalServerError);
resp->setBody(Psc::JSON::object({{"error", "unknown error"}}).to_json_string());
}
callback(resp);
co_return;
});
},
{drogon::Post}
);
return *this;
}
Web_Server& Get(const std::string& pattern, Handler handler) {
drogon::app().registerHandlerViaRegex(
pattern,
[handler](const drogon::HttpRequestPtr& request,
std::function<void(const drogon::HttpResponsePtr&)>&& callback) {
auto resp = drogon::HttpResponse::newHttpResponse();
resp->setContentTypeCode(drogon::CT_APPLICATION_JSON);
handler(request, resp);
callback(resp);
},
{drogon::Get}
);
return *this;
}
Web_Server& GetCoro(const std::string& pattern, CoroHandler handler) {
drogon::app().registerHandlerViaRegex(
pattern,
[handler = std::move(handler)](
const drogon::HttpRequestPtr& request,
std::function<void(const drogon::HttpResponsePtr&)>&& callback) {
auto resp = drogon::HttpResponse::newHttpResponse();
resp->setContentTypeCode(drogon::CT_APPLICATION_JSON);
drogon::async_run(
[handler, request, resp, callback = std::move(callback)]() mutable -> drogon::Task<> {
try {
co_await handler(request, resp);
} catch (const std::exception& error) {
resp->setStatusCode(drogon::k500InternalServerError);
resp->setBody(Psc::JSON::object({{"error", std::string(error.what())}}).to_json_string());
} catch (...) {
resp->setStatusCode(drogon::k500InternalServerError);
resp->setBody(Psc::JSON::object({{"error", "unknown error"}}).to_json_string());
}
callback(resp);
co_return;
});
},
{drogon::Get}
);
return *this;
}
};
// 这个对象不释放
class Mlat_MSG {
public:
explicit Mlat_MSG(const std::shared_ptr<SSR::Mode_Msg>& first) { list.push_back(first);}
[[nodiscard]] std::optional<std::string> icao() const {
auto a = list[0];
auto t = a->type;
if (t == SSR::Mode_Msg::T::S7 || t == SSR::Mode_Msg::T::S14) {
return dynamic_cast<SSR::Mode_S_Msg*>(a.get())->icao;
}
return std::nullopt;
}
[[nodiscard]] std::string msg_hex() const { return list[0]->msg_hex;}
[[nodiscard]] SSR::Mode_Msg::T type() const { return static_cast<SSR::Mode_Msg::T>(list[0]->type);}
[[nodiscard]] SSR::MLAT_timestamp& timestamp() const { return list[0]->mlat_timestamp;}
[[nodiscard]] std::shared_ptr<SSR::Data_Source_Interface> data_source() const { return list[0]->source;}
void add(const std::shared_ptr<SSR::Mode_Msg>& t) {
list.push_back(t);
}
[[nodiscard]] size_t size() const { return list.size(); }
std::vector<std::shared_ptr<SSR::Mode_Msg>> list;
};
class Mlat_Handler {
public:
std::list<Mlat_MSG> get_all() {
std::lock_guard<std::mutex> gg(ok_mtx);
if (ok_list.empty()) return {};
std::list<Mlat_MSG> ret;
std::swap(ok_list, ret);
return ret;
}
void push(const std::shared_ptr<SSR::Mode_Msg>& msg) {
std::lock_guard<std::mutex> g(mtx);
if (list.empty()) {
list.emplace_back(msg);
return;
}
auto time = msg->mlat_timestamp;
auto p = list.rbegin();
while (p != list.rend()) {
auto cur_time = p->timestamp();
// 往前最多找3秒
if (cur_time.daysec + 3 < time.daysec) {
std::lock_guard<std::mutex> gg(ok_mtx);
ok_list.splice(ok_list.end(), list, list.begin(), p.base());
return;
}
if (p->msg_hex() == msg->msg_hex) {
p->add(msg);
return;
}
++p;
}
list.insert(p.base(), Mlat_MSG(msg));
}
protected:
std::list<Mlat_MSG> ok_list;
std::list<Mlat_MSG> list;
std::mutex ok_mtx;
std::mutex mtx;
};
class Global : public Config, public Singleton<Global>{
public:
// asio::io_context ctx;
std::atomic<bool> init_ok{false};
Global();
~Global();
Detach_Thread_Manager thread_manager;
std::shared_ptr<Data_Source> source(const std::string& data_source_key) {
return mode_acs.data_source_config.map.get(data_source_key).value_or(nullptr);
}
std::shared_ptr<Data_Source> total_source() {
for (auto i : mode_acs.data_source_config.map.list())
{
if (i->enable) return i;
}
return mode_acs.data_source_config.map.list().at(0);
}
Web_Server svr;
std::string api = "/api/";
Mlat_Handler mlat_handler;
void init_web_server();
void handle_old_logs();
std::time_t start_server_time;
DELETE_COPY(Global)
};
void handle_buffer_muti_start(std::string& buffer, const std::string& data, const std::set<std::string>& prefix_list,
const std::function<void(std::string&)>& callback);
void handle_buffer_head_tail(std::string& buffer, const std::string& data, const std::string& prefix,
const std::string& suffix, const std::function<void(std::string&)>& callback);