#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 #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 #include #include // 集中 管理日志 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_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; using CoroHandler = std::function(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&& 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&& 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&& 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&& 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& first) { list.push_back(first);} [[nodiscard]] std::optional 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(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(list[0]->type);} [[nodiscard]] SSR::MLAT_timestamp& timestamp() const { return list[0]->mlat_timestamp;} [[nodiscard]] std::shared_ptr data_source() const { return list[0]->source;} void add(const std::shared_ptr& t) { list.push_back(t); } [[nodiscard]] size_t size() const { return list.size(); } std::vector> list; }; class Mlat_Handler { public: std::list get_all() { std::lock_guard gg(ok_mtx); if (ok_list.empty()) return {}; std::list ret; std::swap(ok_list, ret); return ret; } void push(const std::shared_ptr& msg) { std::lock_guard 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 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 ok_list; std::list list; std::mutex ok_mtx; std::mutex mtx; }; class Global : public Config, public Singleton{ public: // asio::io_context ctx; std::atomic init_ok{false}; Global(); ~Global(); Detach_Thread_Manager thread_manager; std::shared_ptr source(const std::string& data_source_key) { return mode_acs.data_source_config.map.get(data_source_key).value_or(nullptr); } std::shared_ptr 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 wake_data_feed_thread(); void io_coro(std::atomic& running); void handle_buffer_muti_start(std::string& buffer, const std::string& data, const std::set& prefix_list, const std::function& callback); void handle_buffer_head_tail(std::string& buffer, const std::string& data, const std::string& prefix, const std::string& suffix, const std::function& callback);