178 lines
6.2 KiB
C++
178 lines
6.2 KiB
C++
#pragma once
|
|
#include <string_view>
|
|
#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_view 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(std::string_view 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(std::string_view host, int port);
|
|
~Web_Server() = default;
|
|
static void stop() {
|
|
std::cout << "开始停止web服务" << std::endl;
|
|
drogon::app().quit();
|
|
}
|
|
Web_Server& Post(std::string_view pattern, Handler handler);
|
|
Web_Server& Post_Coro(std::string_view pattern, CoroHandler handler);
|
|
Web_Server& Get(std::string_view pattern, Handler handler);
|
|
Web_Server& Get_Coro(std::string_view pattern, CoroHandler handler);
|
|
};
|
|
// 这个对象不释放
|
|
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(std::string_view data_source_key) {
|
|
return mode_acs.data_source_config.map.get(std::string(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 init_tiles();
|
|
void handle_old_logs();
|
|
std::time_t start_server_time;
|
|
DELETE_COPY(Global)
|
|
};
|
|
void handle_buffer_muti_start(std::string& buffer, std::string_view data, const std::set<std::string>& prefix_list,
|
|
const std::function<void(std::string&)>& callback);
|
|
void handle_buffer_head_tail(std::string& buffer, std::string_view data, std::string_view prefix,
|
|
std::string_view suffix, const std::function<void(std::string&)>& callback);
|
|
|