From f49c062ffa8e9a0d841e942f4320985648344beb Mon Sep 17 00:00:00 2001 From: wyc <1104749580@qq.com> Date: Fri, 26 Jun 2026 12:05:55 +0800 Subject: [PATCH] =?UTF-8?q?=E6=89=A7=E8=A1=8C=E6=94=B9=E6=88=90=E5=A4=9A?= =?UTF-8?q?=E7=BA=BF=E7=A8=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- module/Local_Server/DSP/DSP_Config.cpp | 579 ++++----- module/Local_Server/Data_Feed/Data_Feed.cpp | 392 +++--- module/Local_Server/Data_Feed/Data_Feed.h | 601 ++++----- .../Local_Server/Data_Source/Data_Source.cpp | 1096 ++++++++--------- module/Local_Server/Data_Source/Data_Source.h | 11 +- .../Data_Source/Data_Source_Handler.cpp | 1089 ++++++++-------- .../Data_Source/Data_Source_Handler.h | 59 +- module/Local_Server/server/With_Loop_Coro.cpp | 66 +- module/Local_Server/server/With_Loop_Coro.h | 42 +- module/Local_Server/server/io_coro.h | 30 +- module/Local_Server_main.cpp | 292 ++--- 11 files changed, 2079 insertions(+), 2178 deletions(-) diff --git a/module/Local_Server/DSP/DSP_Config.cpp b/module/Local_Server/DSP/DSP_Config.cpp index c9f9c3e..ae320b5 100644 --- a/module/Local_Server/DSP/DSP_Config.cpp +++ b/module/Local_Server/DSP/DSP_Config.cpp @@ -1,368 +1,333 @@ - #include "Local_Server/DSP/DSP_Config.h" #include "../server/Global.h" #include "Core/socket/ByteOrder.h" - #include #include #include - #if !USE_PROCESS - // adsb_set_less_30Mhz_ddc_param_t set_less_30Mhz_ddc_param; // adsb_set_less_30Mhz_fft_param_t set_less_30Mhz_fft_param; - decltype(&adsb_set_less_30Mhz_ddc_param) psc_set_less_30Mhz_ddc_param; decltype(&adsb_set_less_30Mhz_fft_param) psc_set_less_30Mhz_fft_param; - #endif - using namespace drogon; // ws://127.0.0.1:8848/chat - -BaseLogger *dsp_logger = nullptr; +BaseLogger* dsp_logger = nullptr; DSP_Config::~DSP_Config() = default; void DSP_Config::close_dsp_device() const { - - auto r = Psc::try_load_function(lib, "adsb_close"); - if (!r) { - Psc::fail_fast(); - } - auto tmp_adsb_close = (decltype(&adsb_close))r.value(); - std::ostringstream oss; - oss << "stop_program ===== " << VAR_STR_1(stop_program) << std::endl; - oss << "DSP_Config adsb_close 开始关闭子库!" << std::endl; - tmp_adsb_close(); - oss << "DSP_Config adsb_close 关闭子库结束!" << std::endl; - dsp_logger->c_debug("dsp", {}, oss.str()); + auto r = Psc::try_load_function(lib, "adsb_close"); + if (!r) { + Psc::fail_fast(); + } + auto tmp_adsb_close = (decltype(&adsb_close))r.value(); + std::ostringstream oss; + oss << "stop_program ===== " << VAR_STR_1(stop_program) << std::endl; + oss << "DSP_Config adsb_close 开始关闭子库!" << std::endl; + tmp_adsb_close(); + oss << "DSP_Config adsb_close 关闭子库结束!" << std::endl; + dsp_logger->c_debug("dsp", {}, oss.str()); } -void DSP_Config::server(Global *g) { - - auto &svr = g->svr; - auto &api = g->api; - std::string name = "dsp"; - - drogon::app().registerWebSocketControllerRegex(R"(^/websocket/.*$)", - "DSP_Ws_Mgr", {Get}); - - ws_iq = Ws_Mgr::instance()->register_ws("/download_iq"); - ws_fft = Ws_Mgr::instance()->register_ws("/get_fft"); - - svr.Post(api + svr.update + name, [this, g](HTTP_Param) { - CHECK_JSON_PARAM - init_update(¶ms); - +void DSP_Config::server(Global* g) { + auto& svr = g->svr; + auto& api = g->api; + std::string name = "dsp"; + drogon::app().registerWebSocketControllerRegex(R"(^/websocket/.*$)", + "DSP_Ws_Mgr", {Get}); + ws_iq = Ws_Mgr::instance()->register_ws("/download_iq"); + ws_fft = Ws_Mgr::instance()->register_ws("/get_fft"); + svr.Post(api + svr.update + name, [this, g](HTTP_Param) { + CHECK_JSON_PARAM + init_update(¶ms); #if USE_PROCESS - adsb_set_less_30Mhz_ddc_param(this->center_freq, this->sample_rate, - this->band_width, 1); - adsb_set_less_30Mhz_fft_param(fft_win_type, fft_point_number, fft_period_ms, - 1); + adsb_set_less_30Mhz_ddc_param(this->center_freq, this->sample_rate, + this->band_width, 1); + adsb_set_less_30Mhz_fft_param(fft_win_type, fft_point_number, fft_period_ms, + 1); #else - psc_set_less_30Mhz_ddc_param(this->center_freq, this->sample_rate, this->band_width, 1); - psc_set_less_30Mhz_fft_param(fft_win_type, fft_point_number, fft_period_ms, 1); + psc_set_less_30Mhz_ddc_param(this->center_freq, this->sample_rate, this->band_width, 1); + psc_set_less_30Mhz_fft_param(fft_win_type, fft_point_number, fft_period_ms, 1); #endif - set_fft_point_number(this->fft_point_number); - g->save(); - res->setBody(warp(to_base_json()).to_json_string()); - }); - svr.Post(api + "get_dsp_config", [this](HTTP_Param) { - res->setBody(warp(to_base_json()).to_json_string()); - }); - - drogon::app().registerHandler( - api + "start_record_iq_stream", - [this](const drogon::HttpRequestPtr &request, - std::function &&callback) { - this->record_iq_stream_ing = true; - auto res = drogon::HttpResponse::newHttpResponse(); - res->setBody("{}"); - callback(res); - }, - {drogon::Post}); - - svr.Post(api + "end_record_iq_stream", [this](HTTP_Param) { - this->record_iq_stream_ing = false; - res->setBody("{}"); - }); - - svr.Post(api + "restart_device", [this](HTTP_Param) { + set_fft_point_number(this->fft_point_number); + g->save(); + res->setBody(warp(to_base_json()).to_json_string()); + }); + svr.Post(api + "get_dsp_config", [this](HTTP_Param) { + res->setBody(warp(to_base_json()).to_json_string()); + }); + drogon::app().registerHandler( + api + "start_record_iq_stream", + [this](const drogon::HttpRequestPtr& request, + std::function&& callback) { + this->record_iq_stream_ing = true; + auto res = drogon::HttpResponse::newHttpResponse(); + res->setBody("{}"); + callback(res); + }, + {drogon::Post}); + svr.Post(api + "end_record_iq_stream", [this](HTTP_Param) { + this->record_iq_stream_ing = false; + res->setBody("{}"); + }); + svr.Post(api + "restart_device", [this](HTTP_Param) { #if USE_PROCESS - restart_device(); + restart_device(); #endif - }); + }); } void DSP_Config::set_fft_point_number(uint64_t new_fft_point_number, bool force) { - fft_point_number = new_fft_point_number; + fft_point_number = new_fft_point_number; #if !USE_PROCESS - std::lock_guard lock(fft_mtx); - if (!force && fft_data.size() == (new_fft_point_number * sizeof(short))) { - return; - } - fft_data.resize(new_fft_point_number * sizeof(short)); + std::lock_guard lock(fft_mtx); + if (!force && fft_data.size() == (new_fft_point_number * sizeof(short))) { + return; + } + fft_data.resize(new_fft_point_number * sizeof(short)); #endif } - #if USE_PROCESS void DSP_Config::adsb_set_less_30Mhz_ddc_param(double center_freq, double sample_rate, double band_width, int sw) { - JSON ret = JSON::object(); - ret.append(JSON("method", "adsb_set_less_30Mhz_ddc_param")); - ret.append(JSON("center_freq", center_freq)); - ret.append(JSON("sample_rate", sample_rate)); - ret.append(JSON("band_width", band_width)); - ret.append(JSON("sw", sw)); - auto d = ret.to_json_string(); - json_func_call.write((uint8_t *)d.data(), d.size()); + JSON ret = JSON::object(); + ret.append(JSON("method", "adsb_set_less_30Mhz_ddc_param")); + ret.append(JSON("center_freq", center_freq)); + ret.append(JSON("sample_rate", sample_rate)); + ret.append(JSON("band_width", band_width)); + ret.append(JSON("sw", sw)); + auto d = ret.to_json_string(); + json_func_call.write((uint8_t*)d.data(), d.size()); } - void DSP_Config::adsb_set_less_30Mhz_fft_param(UHD_FFTWin fft_win_type, size_t fft_point_number, size_t fft_period_ms, int sw) { - JSON ret = JSON::object(); - ret.append(JSON("method", "adsb_set_less_30Mhz_fft_param")); - ret.append(JSON("fft_win_type", fft_win_type)); - ret.append(JSON("fft_point_number", fft_point_number)); - ret.append(JSON("fft_period_ms", fft_period_ms)); - ret.append(JSON("sw", sw)); - auto d = ret.to_json_string(); - json_func_call.write((uint8_t *)d.data(), d.size()); + JSON ret = JSON::object(); + ret.append(JSON("method", "adsb_set_less_30Mhz_fft_param")); + ret.append(JSON("fft_win_type", fft_win_type)); + ret.append(JSON("fft_point_number", fft_point_number)); + ret.append(JSON("fft_period_ms", fft_period_ms)); + ret.append(JSON("sw", sw)); + auto d = ret.to_json_string(); + json_func_call.write((uint8_t*)d.data(), d.size()); } - void DSP_Config::restart_device() { - JSON ret = JSON::object(); - ret.append(JSON("method", "restart_device")); - auto d = ret.to_json_string(); - json_func_call.write((uint8_t *)d.data(), d.size()); + JSON ret = JSON::object(); + ret.append(JSON("method", "restart_device")); + auto d = ret.to_json_string(); + json_func_call.write((uint8_t*)d.data(), d.size()); } #endif - #define USE_ERROR_CBK void DSP_Config::init_env() { - - set_fft_point_number(fft_point_number, true); - auto g = Global::instance(); - Detach_Thread_Manager &manager = g->thread_manager; - - auto handle_iq = [this](void *data) { - uint8_t *pdata = (uint8_t *)data; - auto wi = Ws_Mgr::instance(); - if (!wi) - return; - auto d = (UHD_Struct_KFFT *)(pdata); - if (debug) { - std::ostringstream oss; - oss << "UHD_Struct_KFFT{" - << mem2hex(std::string((char *)pdata, 64), true, " ") << std::endl; - oss << "DataType{" << (int)d->DataType << "} 接收到数据:[" - << "] == " << mem2hex(std::string((char *)pdata + 64, 20), true, " ") - << std::endl; - server_logger->c_debug({}, {}, oss.str()); - } - if (d->DataType == zd_ddc || d->DataType == kd_ddc) { - auto len = d->UsefullLen; - bool cross_the_boundary = len > 2048; - if (cross_the_boundary || debug) { - auto show_len = (size_t)std::min((decltype(len))20, len); - - std::ostringstream oss; - oss << "iq 有效数据长度 【" << len << "】 有效数据: 【" - << std::string((char *)pdata + 64, show_len) << "】" << std::endl; - server_logger->c_debug({}, {}, oss.str()); - } - if (cross_the_boundary) { - std::ostringstream oss; - oss << LOG_POS << "ERROR: ddc iq 回调返回的有效长度越界!" << std::endl; - server_logger->c_debug({}, {}, oss.str()); - return; - } - if (record_iq_stream_ing) { - ws_iq->push_data((const char *)pdata, 2112); - } - } else if (d->DataType == kd_fft) { + set_fft_point_number(fft_point_number, true); + auto g = Global::instance(); + Detach_Thread_Manager& manager = g->thread_manager; + auto handle_iq = [this](void* data) { + uint8_t* pdata = (uint8_t*)data; + auto wi = Ws_Mgr::instance(); + if (!wi) + return; + auto d = (UHD_Struct_KFFT*)(pdata); + if (debug) { + std::ostringstream oss; + oss << "UHD_Struct_KFFT{" + << mem2hex(std::string((char*)pdata, 64), true, " ") << std::endl; + oss << "DataType{" << (int)d->DataType << "} 接收到数据:[" + << "] == " << mem2hex(std::string((char*)pdata + 64, 20), true, " ") + << std::endl; + server_logger->c_debug({}, {}, oss.str()); + } + if (d->DataType == zd_ddc || d->DataType == kd_ddc) { + auto len = d->UsefullLen; + bool cross_the_boundary = len > 2048; + if (cross_the_boundary || debug) { + auto show_len = (size_t)std::min((decltype(len))20, len); + std::ostringstream oss; + oss << "iq 有效数据长度 【" << len << "】 有效数据: 【" + << std::string((char*)pdata + 64, show_len) << "】" << std::endl; + server_logger->c_debug({}, {}, oss.str()); + } + if (cross_the_boundary) { + std::ostringstream oss; + oss << LOG_POS << "ERROR: ddc iq 回调返回的有效长度越界!" << std::endl; + server_logger->c_debug({}, {}, oss.str()); + return; + } + if (record_iq_stream_ing) { + ws_iq->push_data((const char*)pdata, 2112); + } + } + else if (d->DataType == kd_fft) { #if !USE_PROCESS - auto idx = d->Param.FFT.SubFrame; - auto max = fft_point_number / 1024; - if (idx >= max) { - std::ostringstream oss; - oss << "收到了不合法kd_fft Param.FFT.SubFrame " << idx << std::endl; - server_logger->c_debug({}, {}, oss.str()); - return; - } - - std::lock_guard lock(fft_mtx); - auto pos = fft_data.data() + idx * 2048; - memcpy(pos, pdata + 64, 2048); + auto idx = d->Param.FFT.SubFrame; + auto max = fft_point_number / 1024; + if (idx >= max) { + std::ostringstream oss; + oss << "收到了不合法kd_fft Param.FFT.SubFrame " << idx << std::endl; + server_logger->c_debug({}, {}, oss.str()); + return; + } + std::lock_guard lock(fft_mtx); + auto pos = fft_data.data() + idx * 2048; + memcpy(pos, pdata + 64, 2048); #endif - } - }; - + } + }; #if USE_PROCESS - manager.test_and_start_thread( - "读取iq进程数据线程", [this, handle_iq](std::atomic &running) { - while (running) { - uint8_t buf[3000]; - size_t length = 3000; - - while (rb.read(buf, length)) { - Frequency_Limit lm(0.1); - if (lm.test()) { - std::cout << "读取到iq数据" << std::endl; - } - handle_iq(buf); - // auto data = std::string((char *) buf, length); - // if (length != 0) { - // std::cout << "read:【" << length << "】 【" << - // mem2hex(data.substr(64, 20)) << "】" << std::endl; - // } - if (!running) { - break; - } - } - - std::this_thread::sleep_for(std::chrono::microseconds(1)); - } - }); + manager.test_and_start_thread( + "读取iq进程数据线程", [this, handle_iq](std::atomic& running) { + while (running) { + uint8_t buf[3000]; + size_t length = 3000; + while (rb.read(buf, length)) { + Frequency_Limit lm(0.1); + if (lm.test()) { + std::cout << "读取到iq数据" << std::endl; + } + handle_iq(buf); + // auto data = std::string((char *) buf, length); + // if (length != 0) { + // std::cout << "read:【" << length << "】 【" << + // mem2hex(data.substr(64, 20)) << "】" << std::endl; + // } + if (!running) { + break; + } + } + std::this_thread::sleep_for(std::chrono::microseconds(1)); + } + }); #else - manager.test_and_start_thread("iq回调处理", [this, handle_iq]( - std::atomic &running) { - Frequency_Limit_ST limit(frame_rate); - while (running) { - auto list = iq_memory_buffer.get_all(); - if (debug && list.size() > 1000) { - std::ostringstream oss; - oss << "警告: 数据过多 当前数据队列长度:" << list.size() << std::endl; - server_logger->c_debug({}, {}, oss.str()); - } - if (list.empty()) { - std::this_thread::sleep_for(std::chrono::microseconds(1)); - continue; - } - auto wi = Ws_Mgr::instance(); - if (!wi) - continue; - auto frame_number = list.size(); - for (int i = 0; i < frame_number; i++) { - auto pdata = list[i].data(); - handle_iq(pdata); - } - } - }); + manager.test_and_start_thread("iq回调处理", [this, handle_iq]( + std::atomic& running) { + Frequency_Limit_ST limit(frame_rate); + while (running) { + auto list = iq_memory_buffer.get_all(); + if (debug && list.size() > 1000) { + std::ostringstream oss; + oss << "警告: 数据过多 当前数据队列长度:" << list.size() << std::endl; + server_logger->c_debug({}, {}, oss.str()); + } + if (list.empty()) { + std::this_thread::sleep_for(std::chrono::microseconds(1)); + continue; + } + auto wi = Ws_Mgr::instance(); + if (!wi) + continue; + auto frame_number = list.size(); + for (int i = 0; i < frame_number; i++) { + auto pdata = list[i].data(); + handle_iq(pdata); + } + } + }); #endif - - auto interval = 1.0 / (double)frame_rate; - app().getLoop()->runEvery(interval, [this] { - + auto interval = 1.0 / (double)frame_rate; + app().getLoop()->runEvery(interval, [this] { #if USE_PROCESS - wi->ws_get_fft->push_data((const char *)psm.shm.data(), - fft_point_number * 2); + wi->ws_get_fft->push_data((const char*)psm.shm.data(), + fft_point_number * 2); #else - std::lock_guard lock(fft_mtx); - ws_fft->push_data((const char *) fft_data.data(), fft_data.size()); + std::lock_guard lock(fft_mtx); + ws_fft->push_data((const char*)fft_data.data(), fft_data.size()); #endif - }); - + }); #if !USE_PROCESS - - { - auto r = try_load_library(Psc::get_abs_path(library_path)); - if (!r) { - Psc::fail_fast(); - } - lib = r.value(); - } - { - auto r = Psc::try_load_function(lib, "adsb_set_less_30Mhz_ddc_param"); - if (!r) { - Psc::fail_fast(); - } - psc_set_less_30Mhz_ddc_param = (adsb_set_less_30Mhz_ddc_param_t)r.value(); - } - { - auto r = Psc::try_load_function(lib, "adsb_set_less_30Mhz_fft_param"); - if (!r) { - Psc::fail_fast(); - } - psc_set_less_30Mhz_fft_param = (adsb_set_less_30Mhz_fft_param_t)r.value(); - } - using set_iq_cbk_t = decltype(&adsb_set_iq_cbk); - set_iq_cbk_t set_iq_cbk; - { - auto r = Psc::try_load_function(lib, "adsb_set_iq_cbk"); - if (!r) { - Psc::fail_fast(); - } - set_iq_cbk = (set_iq_cbk_t)r.value(); - } - - using adsb_set_error_cbk_t = decltype(&set_error_cbk); - adsb_set_error_cbk_t adsb_set_error_cbk; - { - auto r = Psc::try_load_function(lib, "set_error_cbk"); - if (!r) { - Psc::fail_fast(); - } - adsb_set_error_cbk = (adsb_set_error_cbk_t)r.value(); - } - - psc_set_less_30Mhz_ddc_param(center_freq, sample_rate, band_width, 1); - psc_set_less_30Mhz_fft_param(fft_win_type, fft_point_number, fft_period_ms, - 1); - - set_iq_cbk( - [](void *phandle, void *pdata, uint64_t length) { - if (stop_program != 0) { - static Frequency_Limit fl; - if (fl.test()) { - std::ostringstream oss; - oss << "set_iq_cbk 回调退出:" << signal_to_string(stop_program) - << " " << VAR_STR_1(stop_program) << LOG_POS << std::endl; - dsp_logger->c_debug({}, {}, oss.str()); - } - } - if (length != 2112) { - std::ostringstream oss; - oss << LOG_POS << " IQ回调传入的长度不对!" << std::endl; - dsp_logger->c_debug({}, {}, oss.str()); - return; - } - auto that = (DSP_Config *)phandle; - that->iq_memory_buffer.push(pdata, length); // length 永远等于2112 - }, - (void *)&Global::instance()->dsp_config); - + { + auto r = try_load_library(Psc::get_abs_path(library_path)); + if (!r) { + Psc::fail_fast(); + } + lib = r.value(); + } + { + auto r = Psc::try_load_function(lib, "adsb_set_less_30Mhz_ddc_param"); + if (!r) { + Psc::fail_fast(); + } + psc_set_less_30Mhz_ddc_param = (adsb_set_less_30Mhz_ddc_param_t)r.value(); + } + { + auto r = Psc::try_load_function(lib, "adsb_set_less_30Mhz_fft_param"); + if (!r) { + Psc::fail_fast(); + } + psc_set_less_30Mhz_fft_param = (adsb_set_less_30Mhz_fft_param_t)r.value(); + } + using set_iq_cbk_t = decltype(&adsb_set_iq_cbk); + set_iq_cbk_t set_iq_cbk; + { + auto r = Psc::try_load_function(lib, "adsb_set_iq_cbk"); + if (!r) { + Psc::fail_fast(); + } + set_iq_cbk = (set_iq_cbk_t)r.value(); + } + using adsb_set_error_cbk_t = decltype(&set_error_cbk); + adsb_set_error_cbk_t adsb_set_error_cbk; + { + auto r = Psc::try_load_function(lib, "set_error_cbk"); + if (!r) { + Psc::fail_fast(); + } + adsb_set_error_cbk = (adsb_set_error_cbk_t)r.value(); + } + psc_set_less_30Mhz_ddc_param(center_freq, sample_rate, band_width, 1); + psc_set_less_30Mhz_fft_param(fft_win_type, fft_point_number, fft_period_ms, + 1); + set_iq_cbk( + [](void* phandle, void* pdata, uint64_t length) { + if (stop_program != 0) { + static Frequency_Limit fl; + if (fl.test()) { + std::ostringstream oss; + oss << "set_iq_cbk 回调退出:" << signal_to_string(stop_program) + << " " << VAR_STR_1(stop_program) << LOG_POS_SIMPLE << std::endl; + dsp_logger->c_debug({}, {}, oss.str()); + } + } + if (length != 2112) { + std::ostringstream oss; + oss << LOG_POS << " IQ回调传入的长度不对!" << std::endl; + dsp_logger->c_debug({}, {}, oss.str()); + return; + } + auto that = (DSP_Config*)phandle; + that->iq_memory_buffer.push(pdata, length); // length 永远等于2112 + }, + (void*)&Global::instance()->dsp_config); #ifdef USE_ERROR_CBK - - adsb_set_error_cbk([](const char *file_name, const char *func_name, - const char *err_msg) { - if (stop_program != 0) { - static Frequency_Limit fl; - if (fl.test()) { - std::ostringstream oss; - oss << "adsb_set_error_cbk 回调退出:" << signal_to_string(stop_program) - << " " << VAR_STR_1(stop_program) << LOG_POS << std::endl; - dsp_logger->c_debug({}, {}, oss.str()); - } - return; - } - Log_Type lt{{}, - { - {"file_name", std::string(file_name)}, - {"func_name", std::string(func_name)}, - }}; - dsp_logger->debug({}, lt, std::string(err_msg)); - }); + adsb_set_error_cbk([](const char* file_name, const char* func_name, + const char* err_msg) { + if (stop_program != 0) { + static Frequency_Limit fl(3.0); + if (fl.test()) { + std::ostringstream oss; + oss << "adsb_set_error_cbk 回调退出:" << signal_to_string(stop_program) + << " " << VAR_STR_1(stop_program) << LOG_POS << std::endl; + dsp_logger->c_debug({}, {}, oss.str()); + } + return; + } + Log_Type lt{ + {}, + { + {"file_name", std::string(file_name)}, + {"func_name", std::string(func_name)}, + } + }; + dsp_logger->debug({}, lt, std::string(err_msg)); + }); #endif - #else - adsb_set_less_30Mhz_ddc_param(center_freq, sample_rate, band_width, 1); - adsb_set_less_30Mhz_fft_param(fft_win_type, fft_point_number, fft_period_ms, - 1); + adsb_set_less_30Mhz_ddc_param(center_freq, sample_rate, band_width, 1); + adsb_set_less_30Mhz_fft_param(fft_win_type, fft_point_number, fft_period_ms, + 1); #endif } diff --git a/module/Local_Server/Data_Feed/Data_Feed.cpp b/module/Local_Server/Data_Feed/Data_Feed.cpp index 4d55a7a..1bf07e6 100644 --- a/module/Local_Server/Data_Feed/Data_Feed.cpp +++ b/module/Local_Server/Data_Feed/Data_Feed.cpp @@ -2,243 +2,189 @@ #include "../server/Global.h" bool Data_Feed::registered() { - auto all_feed = Global::instance()->mode_acs.data_feed_config.map.list(); - for (auto &item : all_feed) { - if (item.get() == this) { - return true; - } - } - return false; + auto all_feed = Global::instance()->mode_acs.data_feed_config.map.list(); + for (auto& item : all_feed) { + if (item.get() == this) { + return true; + } + } + return false; } + concurrencpp::result Data_Feed_UDP_Server::handle_in_loop_coro() { - co_await svr.tick_coro(); - co_return; + co_await svr.tick_coro(); + co_return; } -concurrencpp::result -Data_Feed_UDP_Server::send_coro(const std::string &data) { - co_await svr.write_to_all_clients_coro(data); - co_return; +concurrencpp::result Data_Feed_UDP_Server::send_coro(const std::string& data) { + co_await svr.write_to_all_clients_coro(data); + co_return; } + concurrencpp::result Data_Feed_UDP_Server::_open() { - svr.set_bind_address("0.0.0.0", port); - svr.create(); - server_logger->c_debug({}, {}, to_string() + "开启!"); - co_return; -} -JSON Data_feed_Config::get_feed(const std::string &key) { - auto ret = map.get(key); - if (ret.has_value()) { - auto r = ret.value().get(); - return r->to_json(); - } - return {nullptr}; + svr.set_bind_address("0.0.0.0", port); + svr.create(); + server_logger->c_debug({}, {}, to_string() + "开启!"); + co_return; } -void Data_feed_Config::server(Global *g) { - auto &svr = g->svr; - auto &api = g->api; - std::string name = "data_feed"; - - svr.Post(api + "get_data_feed_state", [this](HTTP_Param) { - CHECK_JSON_PARAM - HTTP_REQUIRE_VALUE(key, params.try_get_string("key")) - auto t = map.get(key); - JSON ret{nullptr}; - if (t.has_value()) { - ret = t.value()->get_state_json(); - } - res->setBody(warp(ret).to_json_string()); - }); - - svr.Post(api + "update_data_feed_config", [this](HTTP_Param) { - CHECK_JSON_PARAM - Get_J(packet_byte_size) Get_J(empty_wait_milliseconds) - res->setBody(warp(to_json()).to_json_string()); - Global::save(); - }); - - svr.Post(api + "get_data_feed_config", [this](HTTP_Param) { - res->setBody(warp(to_json()).to_json_string()); - }); - - svr.Post(api + "get_data_feed_server_connect", [this](HTTP_Param) { - CHECK_JSON_PARAM - HTTP_REQUIRE_VALUE(key, params.try_get_string("key")) - auto t = map.get(key); - JSON ret{nullptr}; - if (t.has_value()) { - auto dfs = dynamic_cast(t.value().get()); - if (dfs) { - ret = dfs->get_clients_json(); - } - auto dfs2 = dynamic_cast(t.value().get()); - if (dfs2) { - ret = dfs2->get_clients_json(); - } - } - res->setBody(warp(ret).to_json_string()); - }); - - svr.Post(api + svr.search + name, [this](HTTP_Param) { - CHECK_JSON_PARAM - HTTP_REQUIRE_VALUE(type, params.try_get_string("key")) - res->setBody(warp(get_feed(type)).to_json_string()); - }); - - svr.Post(api + svr.update + name, [g, this](HTTP_Param) { - CHECK_JSON_PARAM - HTTP_REQUIRE_VALUE(key, params.try_get_string("key")) - HTTP_REQUIRE_VALUE(t, map.get(key)) - // 直接关闭 - // t->close(); - t->from_json(¶ms); - // if (t->enable) { - // t->check_and_open(); - // } - Global::save(); - g->mode_acs.source_feed_relation_config.set_need_refresh(); - }); - - svr.Post(api + svr.insert + name, [g, this](HTTP_Param) { - CHECK_JSON_PARAM - HTTP_REQUIRE_VALUE(index, params.try_get_number("index")) - HTTP_REQUIRE_PTR(data, params.get("data")) - HTTP_REQUIRE_VALUE(t, data->try_get_string("type")) - auto df = create_data_feed_from_type(t); - df->from_json(data); - HTTP_REQUIRE_VALUE(enable, data->try_get_bool("enable")) - // if (enable) - // { - // df->check_and_open(); - // } - HTTP_REQUIRE_TRUE(map.insert(index, df), "index") - res->setBody(warp(to_json()).to_json_string()); - Global::save(); - g->mode_acs.source_feed_relation_config.set_need_refresh(); - }); - - svr.Post(api + svr.remove + name, [g, this](HTTP_Param) { - CHECK_JSON_PARAM - HTTP_REQUIRE_VALUE(index, params.try_get_number("index")) - HTTP_REQUIRE_VALUE(df, map.try_get(index)) - df->async_stop(); - HTTP_REQUIRE_TRUE(map.remove(index), "index") - g->save(); - res->setBody(warp(to_json()).to_json_string()); - g->mode_acs.source_feed_relation_config.set_need_refresh(); - }); - - svr.Post(api + svr.rise + name, [g, this](HTTP_Param) { - CHECK_JSON_PARAM - HTTP_REQUIRE_VALUE(index, params.try_get_number("index")) - HTTP_REQUIRE_TRUE(map.swap(index, index - 1), "index") - g->save(); - res->setBody(warp(to_json()).to_json_string()); - g->mode_acs.source_feed_relation_config.set_need_refresh(); - }); - svr.Post(api + svr.fall + name, [g, this](HTTP_Param) { - CHECK_JSON_PARAM - HTTP_REQUIRE_VALUE(index, params.try_get_number("index")) - HTTP_REQUIRE_TRUE(map.swap(index, index + 1), "index") - g->save(); - res->setBody(warp(to_json()).to_json_string()); - g->mode_acs.source_feed_relation_config.set_need_refresh(); - }); +JSON Data_feed_Config::get_feed(const std::string& key) { + auto ret = map.get(key); + if (ret.has_value()) { + auto r = ret.value().get(); + return r->to_json(); + } + return {nullptr}; } -void BIN_Msg_Buffer::push(const std::string &msg) { - auto output_packet_size = - Global::instance()->mode_acs.data_feed_config.packet_byte_size.load(); - std::lock_guard g(mtx); - auto &pool = Global::instance()->mode_acs.data_feed_config.pool_; - if (msg_list_cache.empty() || - msg_list_cache.back()->size() > output_packet_size) { - auto t = pool.get(); - t->append(msg); - msg_list_cache.push_back(t); - } else { - msg_list_cache.back()->append(msg); - } +void Data_feed_Config::server(Global* g) { + auto& svr = g->svr; + auto& api = g->api; + std::string name = "data_feed"; + svr.Post(api + "get_data_feed_state", [this](HTTP_Param) { + CHECK_JSON_PARAM + HTTP_REQUIRE_VALUE(key, params.try_get_string("key")) + auto t = map.get(key); + JSON ret{nullptr}; + if (t.has_value()) { + ret = t.value()->get_state_json(); + } + res->setBody(warp(ret).to_json_string()); + }); + svr.Post(api + "update_data_feed_config", [this](HTTP_Param) { + CHECK_JSON_PARAM + Get_J(packet_byte_size) + Get_J(empty_wait_milliseconds) + res->setBody(warp(to_json()).to_json_string()); + Global::save(); + }); + svr.Post(api + "get_data_feed_config", [this](HTTP_Param) { + res->setBody(warp(to_json()).to_json_string()); + }); + svr.Post(api + "get_data_feed_server_connect", [this](HTTP_Param) { + CHECK_JSON_PARAM + HTTP_REQUIRE_VALUE(key, params.try_get_string("key")) + auto t = map.get(key); + JSON ret{nullptr}; + if (t.has_value()) { + auto dfs = dynamic_cast(t.value().get()); + if (dfs) { + ret = dfs->get_clients_json(); + } + auto dfs2 = dynamic_cast(t.value().get()); + if (dfs2) { + ret = dfs2->get_clients_json(); + } + } + res->setBody(warp(ret).to_json_string()); + }); + svr.Post(api + svr.search + name, [this](HTTP_Param) { + CHECK_JSON_PARAM + HTTP_REQUIRE_VALUE(type, params.try_get_string("key")) + res->setBody(warp(get_feed(type)).to_json_string()); + }); + svr.Post(api + svr.update + name, [g, this](HTTP_Param) { + CHECK_JSON_PARAM + HTTP_REQUIRE_VALUE(key, params.try_get_string("key")) + HTTP_REQUIRE_VALUE(t, map.get(key)) + // 直接关闭 + // t->close(); + t->from_json(¶ms); + // if (t->enable) { + // t->check_and_open(); + // } + Global::save(); + g->mode_acs.source_feed_relation_config.set_need_refresh(); + }); + svr.Post(api + svr.insert + name, [g, this](HTTP_Param) { + CHECK_JSON_PARAM + HTTP_REQUIRE_VALUE(index, params.try_get_number("index")) + HTTP_REQUIRE_PTR(data, params.get("data")) + HTTP_REQUIRE_VALUE(t, data->try_get_string("type")) + auto df = create_data_feed_from_type(t); + df->from_json(data); + HTTP_REQUIRE_VALUE(enable, data->try_get_bool("enable")) + // if (enable) + // { + // df->check_and_open(); + // } + HTTP_REQUIRE_TRUE(map.insert(index, df), "index") + res->setBody(warp(to_json()).to_json_string()); + Global::save(); + g->mode_acs.source_feed_relation_config.set_need_refresh(); + }); + svr.Post(api + svr.remove + name, [g, this](HTTP_Param) { + CHECK_JSON_PARAM + HTTP_REQUIRE_VALUE(index, params.try_get_number("index")) + HTTP_REQUIRE_VALUE(df, map.try_get(index)) + df->async_stop(); + HTTP_REQUIRE_TRUE(map.remove(index), "index") + g->save(); + res->setBody(warp(to_json()).to_json_string()); + g->mode_acs.source_feed_relation_config.set_need_refresh(); + }); + svr.Post(api + svr.rise + name, [g, this](HTTP_Param) { + CHECK_JSON_PARAM + HTTP_REQUIRE_VALUE(index, params.try_get_number("index")) + HTTP_REQUIRE_TRUE(map.swap(index, index - 1), "index") + g->save(); + res->setBody(warp(to_json()).to_json_string()); + g->mode_acs.source_feed_relation_config.set_need_refresh(); + }); + svr.Post(api + svr.fall + name, [g, this](HTTP_Param) { + CHECK_JSON_PARAM + HTTP_REQUIRE_VALUE(index, params.try_get_number("index")) + HTTP_REQUIRE_TRUE(map.swap(index, index + 1), "index") + g->save(); + res->setBody(warp(to_json()).to_json_string()); + g->mode_acs.source_feed_relation_config.set_need_refresh(); + }); } -const std::vector &BIN_Msg_Buffer::get_all() { - std::lock_guard g(mtx); - std::swap(msg_list_cache, msg_list); - msg_list_cache.clear(); - mode_s_msg_num = 0; - mode_other_msg_num = 0; - return msg_list; + +void BIN_Msg_Buffer::push(const std::string& msg) { + auto output_packet_size = + Global::instance()->mode_acs.data_feed_config.packet_byte_size.load(); + std::lock_guard g(mtx); + auto& pool = Global::instance()->mode_acs.data_feed_config.pool_; + if (msg_list_cache.empty() || + msg_list_cache.back()->size() > output_packet_size) { + auto t = pool.get(); + t->append(msg); + msg_list_cache.push_back(t); + } + else { + msg_list_cache.back()->append(msg); + } } + +const std::vector& BIN_Msg_Buffer::get_all() { + std::lock_guard g(mtx); + std::swap(msg_list_cache, msg_list); + msg_list_cache.clear(); + mode_s_msg_num = 0; + mode_other_msg_num = 0; + return msg_list; +} + BIN_Msg_Buffer::BIN_Msg_Buffer() { - msg_list_cache.reserve(8 * 1024); - msg_list.reserve(8 * 1024); + msg_list_cache.reserve(8 * 1024); + msg_list.reserve(8 * 1024); } + Psc::JSON BIN_Msg_Buffer::state_json() { - - auto output_packet_size = - Global::instance()->mode_acs.data_feed_config.packet_byte_size.load(); - size_t size, cache_size, pool_capacity, pool_free_count; - { - std::lock_guard g(mtx); - auto &pool = Global::instance()->mode_acs.data_feed_config.pool_; - size = msg_list.size(); - cache_size = msg_list_cache.size(); - pool_capacity = pool.capacity(); - pool_free_count = pool.free_count(); - } - return VAR_JSON_7(mode_s_msg_num, mode_other_msg_num, output_packet_size, - cache_size, size, pool_capacity, pool_free_count); + auto output_packet_size = + Global::instance()->mode_acs.data_feed_config.packet_byte_size.load(); + size_t size, cache_size, pool_capacity, pool_free_count; + { + std::lock_guard g(mtx); + auto& pool = Global::instance()->mode_acs.data_feed_config.pool_; + size = msg_list.size(); + cache_size = msg_list_cache.size(); + pool_capacity = pool.capacity(); + pool_free_count = pool.free_count(); + } + return VAR_JSON_7(mode_s_msg_num, mode_other_msg_num, output_packet_size, + cache_size, size, pool_capacity, pool_free_count); } -concurrencpp::result Data_Feed::loop_coro( - std::shared_ptr executor_) { - auto feed = this; - co_await concurrencpp::resume_on(executor_); - auto &mode_acs = Global::instance()->mode_acs; - auto &cfg = mode_acs.data_feed_config; - auto &pool = cfg.pool_; - auto &report_data_feed_msg_mum = mode_acs.report_data_feed_msg_mum; - while (feed->enable) { - std::vector messages; - { - if (!feed->running() || !feed->registered()) { - break; - } - co_await feed->handle_in_loop_coro(); - auto s_num = feed->msg_buffer.mode_s_msg_num.load(); - auto other_num = feed->msg_buffer.mode_other_msg_num.load(); - const std::vector &all = feed->msg_buffer.get_all(); - Pool_Guard pg(&pool, all); - auto num = report_data_feed_msg_mum.load(); - auto monitor_msg_live = mode_acs.monitor_msg_live.load(); - if (monitor_msg_live && num != 0 && all.size() > num && - too_many_msg_limit.test()) { - std::ostringstream oss; - oss << "feed_key:" << feed->key << " "; - oss << "recv_s:" << s_num << " "; - oss << "recv_other:" << other_num << " "; - std::cout << oss.str() << std::endl; - } - messages.reserve(all.size()); - for (const auto *str : all) { - if (!str || str->empty()) { - std::cout << "empty feed message:" << feed->key << std::endl; - continue; - } - messages.emplace_back(*str); - } - } - if (messages.empty()) { - co_await concurrencpp::resume_on(executor_); - continue; - } - if (!feed->running() || !feed->registered()) { - break; - } - for (auto &msg : messages) { - co_await feed->send_coro(msg); - } - co_await concurrencpp::resume_on(executor_); - } - co_return; -} + diff --git a/module/Local_Server/Data_Feed/Data_Feed.h b/module/Local_Server/Data_Feed/Data_Feed.h index b588126..8d5c113 100644 --- a/module/Local_Server/Data_Feed/Data_Feed.h +++ b/module/Local_Server/Data_Feed/Data_Feed.h @@ -5,319 +5,360 @@ enum class Output_Data_Format { AVR, AVR_MLAT, BIN, SBS, BIN_ID }; enum class Mode_S_Output_Type { DF_11_17_18, NO_POS_Mode_S, ALL_Mode_S }; struct Output_Format { - Output_Data_Format type = Output_Data_Format::BIN; - Psc::Copyable_Atomic use_status = false; - Mode_S_Output_Type mode_s_output_type = Mode_S_Output_Type::DF_11_17_18; - Psc::Copyable_Atomic use_mode_ac = false; - Psc::Copyable_Atomic sbs_only_pos = false; - PSC_USE_JSON + Output_Data_Format type = Output_Data_Format::BIN; + Psc::Copyable_Atomic use_status = false; + Mode_S_Output_Type mode_s_output_type = Mode_S_Output_Type::DF_11_17_18; + Psc::Copyable_Atomic use_mode_ac = false; + Psc::Copyable_Atomic sbs_only_pos = false; + PSC_USE_JSON }; class Data_Feed : public With_Loop_Coro { public: - BIN_Msg_Buffer msg_buffer{}; - Output_Format output_format; - Frequency_Limit_Multi sbs_flm{}; - concurrencpp::result loop_coro( - std::shared_ptr executor) override; - virtual void handle_in_loop() {} - virtual concurrencpp::result handle_in_loop_coro() { - handle_in_loop(); - co_return; - } - virtual concurrencpp::result send_coro(const std::string&) { - co_return; - } - virtual Psc::JSON to_json() { - Psc::JSON ret = With_Loop_Coro::to_base_json(); - ret += output_format.to_base_json(); - return ret; - } - virtual void from_json(const Psc::JSON* that_json) { - With_Loop_Coro::from_base_json(that_json); - output_format.from_base_json(that_json->get("output_format")); - } - virtual Psc::JSON get_custom_state_json() { - return Psc::JSON::object(); - } - virtual Psc::JSON get_state_json() { - Psc::JSON ret = msg_buffer.state_json(); - ret += get_custom_state_json(); - return ret; - } - std::string to_string() { - return "Data_Feed{" + VAR_STR_3(key, enable, type) + "}"; - } - bool registered(); + BIN_Msg_Buffer msg_buffer{}; + Output_Format output_format; + Frequency_Limit_Multi sbs_flm{}; + concurrencpp::result loop_coro() final; + virtual void handle_in_loop() {} + + virtual concurrencpp::result handle_in_loop_coro() { + handle_in_loop(); + co_return; + } + + virtual concurrencpp::result send_coro(const std::string&) { + co_return; + } + + virtual Psc::JSON to_json() { + Psc::JSON ret = With_Loop_Coro::to_base_json(); + ret.append(Psc::JSON("output_format", output_format.to_base_json())); + return ret; + } + + virtual void from_json(const Psc::JSON* that_json) { + With_Loop_Coro::from_base_json(that_json); + output_format.from_base_json(that_json->get("output_format")); + } + + virtual Psc::JSON get_custom_state_json() { + return Psc::JSON::object(); + } + + virtual Psc::JSON get_state_json() { + Psc::JSON ret = msg_buffer.state_json(); + ret += get_custom_state_json(); + return ret; + } + + std::string to_string() { + return "Data_Feed{" + VAR_STR_3(key, enable, type) + "}"; + } + + bool registered(); protected: - Data_Feed() = default; - Frequency_Limit too_many_msg_limit; + Data_Feed() = default; + Frequency_Limit too_many_msg_limit; }; class Data_Feed_TCP_Server_Data { public: - std::uint16_t port{}; - size_t connect_user_buffer_size{}; - size_t connect_system_buffer_size{}; - PSC_USE_JSON + std::uint16_t port{}; + size_t connect_user_buffer_size{}; + size_t connect_system_buffer_size{}; + PSC_USE_JSON }; class Data_Feed_TCP_Server : public Data_Feed, public Data_Feed_TCP_Server_Data { public: - Psc::asio_socket::TCP_Server_Coro svr; - Psc::JSON get_custom_state_json() override { - auto& state = svr.state; - Psc::JSON ret = Psc::JSON::object(); - Ret_J(connect_system_buffer_size) - Ret_J(connect_user_buffer_size) - ret.key = "fixed"; - auto t = VAR_JSON_1(state); - t.append(ret); - return t; - } - ~Data_Feed_TCP_Server() override = default; - concurrencpp::result handle_in_loop_coro() override { - co_await svr.flush_clients_coro(); - co_await svr.tick_coro(); - co_return; - } - concurrencpp::result send_coro(const std::string& data) override { - co_await svr.write_to_all_clients_coro(data); - co_return; - } - void from_json(const Psc::JSON* that_json) override { - Data_Feed::from_json(that_json); - Data_Feed_TCP_Server_Data::from_base_json(that_json); - } - Psc::JSON to_json() override { - Psc::JSON ret = Data_Feed::to_json(); - ret += Data_Feed_TCP_Server_Data::to_base_json(); - return ret; - } - concurrencpp::result _close() override { - co_await svr.close_coro(); - co_return; - } - concurrencpp::result _open() override { - svr.set_connect_user_buffer_size(connect_user_buffer_size); - svr.set_connect_system_buffer_size(connect_system_buffer_size); - svr.set_tcp_no_delay(false); - svr.create(); - co_await svr.listen_coro("0.0.0.0", port); - co_return; - } - Psc::JSON get_clients_json() { - Psc::JSON ret = Psc::JSON::array(); - for (const auto& conn : svr.get_all_clients()) { - auto& info = conn->info; - Psc::JSON cur = Psc::JSON::object(); - auto& fd = info.fd; - auto& cur_ip = info.sockaddr.ip; - auto& cur_port = info.sockaddr.port; - cur.append({"base", VAR_STR_3(cur_ip, cur_port, fd)}); - cur.append({"state", conn->send_buffer.state_str()}); - { - auto& ins = conn->push_speed.instant_speed; - auto& avr = conn->push_speed.average_speed; - cur.append({"send_speed(KB/s)", VAR_STR_2(ins, avr)}); - } - { - auto& ins = conn->lose_speed.instant_speed; - auto& avr = conn->lose_speed.average_speed; - cur.append({"lose_speed(KB/s)", VAR_STR_2(ins, avr)}); - } - { - auto& ins = conn->send_num.instant; - auto& avr = conn->send_num.average; - cur.append({"send_num(byte/count)", VAR_STR_2(ins, avr)}); - } - ret.append(cur); - } - return ret; - } + Psc::asio_socket::TCP_Server_Coro svr; + + Psc::JSON get_custom_state_json() override { + auto& state = svr.state; + Psc::JSON ret = Psc::JSON::object(); + Ret_J(connect_system_buffer_size) + Ret_J(connect_user_buffer_size) + ret.key = "fixed"; + auto t = VAR_JSON_1(state); + t.append(ret); + return t; + } + + ~Data_Feed_TCP_Server() override = default; + + concurrencpp::result handle_in_loop_coro() override { + co_await svr.flush_clients_coro(); + co_await svr.tick_coro(); + co_return; + } + + concurrencpp::result send_coro(const std::string& data) override { + co_await svr.write_to_all_clients_coro(data); + co_return; + } + + void from_json(const Psc::JSON* that_json) override { + Data_Feed::from_json(that_json); + Data_Feed_TCP_Server_Data::from_base_json(that_json); + } + + Psc::JSON to_json() override { + Psc::JSON ret = Data_Feed::to_json(); + ret += Data_Feed_TCP_Server_Data::to_base_json(); + return ret; + } + + concurrencpp::result _close() override { + co_await svr.close_coro(); + co_return; + } + + concurrencpp::result _open() override { + svr.set_connect_user_buffer_size(connect_user_buffer_size); + svr.set_connect_system_buffer_size(connect_system_buffer_size); + svr.set_tcp_no_delay(false); + svr.create(); + co_await svr.listen_coro("0.0.0.0", port); + co_return; + } + + Psc::JSON get_clients_json() { + Psc::JSON ret = Psc::JSON::array(); + for (const auto& conn : svr.get_all_clients()) { + auto& info = conn->info; + Psc::JSON cur = Psc::JSON::object(); + auto& fd = info.fd; + auto& cur_ip = info.sockaddr.ip; + auto& cur_port = info.sockaddr.port; + cur.append({"base", VAR_STR_3(cur_ip, cur_port, fd)}); + cur.append({"state", conn->send_buffer.state_str()}); + { + auto& ins = conn->push_speed.instant_speed; + auto& avr = conn->push_speed.average_speed; + cur.append({"send_speed(KB/s)", VAR_STR_2(ins, avr)}); + } + { + auto& ins = conn->lose_speed.instant_speed; + auto& avr = conn->lose_speed.average_speed; + cur.append({"lose_speed(KB/s)", VAR_STR_2(ins, avr)}); + } + { + auto& ins = conn->send_num.instant; + auto& avr = conn->send_num.average; + cur.append({"send_num(byte/count)", VAR_STR_2(ins, avr)}); + } + ret.append(cur); + } + return ret; + } }; class Data_Feed_TCP_Client_Data { public: - std::string url; - std::uint16_t port{}; - PSC_USE_JSON + std::string url; + std::uint16_t port{}; + PSC_USE_JSON }; class Data_Feed_TCP_Client : public Data_Feed, public Data_Feed_TCP_Client_Data { public: - concurrencpp::result handle_in_loop_coro() override { - co_await cli.tick_coro(); - co_return; - } - concurrencpp::result send_coro(const std::string& data) override { - co_await cli.send_coro(data); - co_return; - } - std::string url; - Psc::JSON get_custom_state_json() override { - auto& state = cli.state; - return VAR_JSON_1(state); - } - std::uint16_t port{}; - Psc::asio_socket::TCP_Client_Coro cli; - ~Data_Feed_TCP_Client() override = default; - concurrencpp::result _close() override { - co_await cli.close_coro(); - co_return; - } - concurrencpp::result _open() override { - Psc::asio_socket::Sockaddr_In sockaddr_in; - sockaddr_in.ip = url; - sockaddr_in.port = port; - cli.set_dest_address(sockaddr_in); - cli.create(); - co_await cli.connect_coro(); - co_return; - } - void from_json(const Psc::JSON* that_json) override { - Data_Feed::from_json(that_json); - Data_Feed_TCP_Client_Data::from_base_json(that_json); - } - Psc::JSON to_json() override { - return Data_Feed::to_json() += Data_Feed_TCP_Client_Data::to_base_json(); - } + concurrencpp::result handle_in_loop_coro() override { + co_await cli.tick_coro(); + co_return; + } + + concurrencpp::result send_coro(const std::string& data) override { + co_await cli.send_coro(data); + co_return; + } + + std::string url; + + Psc::JSON get_custom_state_json() override { + auto& state = cli.state; + return VAR_JSON_1(state); + } + + std::uint16_t port{}; + Psc::asio_socket::TCP_Client_Coro cli; + ~Data_Feed_TCP_Client() override = default; + + concurrencpp::result _close() override { + co_await cli.close_coro(); + co_return; + } + + concurrencpp::result _open() override { + Psc::asio_socket::Sockaddr_In sockaddr_in; + sockaddr_in.ip = url; + sockaddr_in.port = port; + cli.set_dest_address(sockaddr_in); + cli.create(); + co_await cli.connect_coro(); + co_return; + } + + void from_json(const Psc::JSON* that_json) override { + Data_Feed::from_json(that_json); + Data_Feed_TCP_Client_Data::from_base_json(that_json); + } + + Psc::JSON to_json() override { + return Data_Feed::to_json() += Data_Feed_TCP_Client_Data::to_base_json(); + } }; class Data_Feed_UDP_Server_Data { public: - std::uint16_t port{}; - PSC_USE_JSON + std::uint16_t port{}; + PSC_USE_JSON }; class Data_Feed_UDP_Server : public Data_Feed, public Data_Feed_UDP_Server_Data { public: - Psc::JSON get_custom_state_json() override { - auto& state = svr.state; - return VAR_JSON_1(state); - } - Data_Feed_UDP_Server() = default; - ~Data_Feed_UDP_Server() override = default; - concurrencpp::result handle_in_loop_coro() override; - concurrencpp::result send_coro(const std::string& data) override; - [[nodiscard]] Psc::JSON get_clients_json() const { - Psc::JSON ret = Psc::JSON::array(); - for (const auto& i : svr.clients) { - Psc::JSON cur = Psc::JSON::object(); - cur.append({"ip", i.ip}); - cur.append({"port", i.port}); - ret.append(cur); - } - return ret; - } - void from_json(const Psc::JSON* that_json) override { - Data_Feed::from_json(that_json); - Data_Feed_UDP_Server_Data::from_base_json(that_json); - } - Psc::JSON to_json() override { - return Data_Feed::to_json() += Data_Feed_UDP_Server_Data::to_base_json(); - } - concurrencpp::result _close() override { - co_await svr.close_coro(); - co_return; - } - concurrencpp::result _open() override; - Psc::asio_socket::UDP_Server_Coro svr; + Psc::JSON get_custom_state_json() override { + auto& state = svr.state; + return VAR_JSON_1(state); + } + + Data_Feed_UDP_Server() = default; + ~Data_Feed_UDP_Server() override = default; + concurrencpp::result handle_in_loop_coro() override; + concurrencpp::result send_coro(const std::string& data) override; + + [[nodiscard]] Psc::JSON get_clients_json() const { + Psc::JSON ret = Psc::JSON::array(); + for (const auto& i : svr.clients) { + Psc::JSON cur = Psc::JSON::object(); + cur.append({"ip", i.ip}); + cur.append({"port", i.port}); + ret.append(cur); + } + return ret; + } + + void from_json(const Psc::JSON* that_json) override { + Data_Feed::from_json(that_json); + Data_Feed_UDP_Server_Data::from_base_json(that_json); + } + + Psc::JSON to_json() override { + return Data_Feed::to_json() += Data_Feed_UDP_Server_Data::to_base_json(); + } + + concurrencpp::result _close() override { + co_await svr.close_coro(); + co_return; + } + + concurrencpp::result _open() override; + Psc::asio_socket::UDP_Server_Coro svr; }; class Data_Feed_UDP_Client_Data { public: - std::uint16_t port{}; - std::string url{}; - PSC_USE_JSON + std::uint16_t port{}; + std::string url{}; + PSC_USE_JSON }; class Data_Feed_UDP_Client : public Data_Feed, public Data_Feed_UDP_Client_Data { public: - Data_Feed_UDP_Client() {} - ~Data_Feed_UDP_Client() override {} - Psc::JSON get_custom_state_json() override { - auto& state = cli.state; - return VAR_JSON_1(state); - } - concurrencpp::result handle_in_loop_coro() override { - co_await cli.tick_coro(); - co_return; - } - concurrencpp::result send_coro(const std::string& data) override { - co_await cli.send_coro(data); - co_return; - } - Psc::asio_socket::UDP_Client_Coro cli; - void from_json(const Psc::JSON* that_json) override { - Data_Feed::from_json(that_json); - Data_Feed_UDP_Client_Data::from_base_json(that_json); - } - Psc::JSON to_json() override { - return Data_Feed::to_json() += Data_Feed_UDP_Client_Data::to_base_json(); - } - concurrencpp::result _close() override { - std::cout << "udp client target address:" << cli.dest_address.to_string() - << " closed" << std::endl; - co_await cli.close_coro(); - co_return; - } - concurrencpp::result _open() override { - cli.create(); - cli.set_dest_address(url, port); - co_await cli.connect_coro(); - co_return; - } + Data_Feed_UDP_Client() {} + ~Data_Feed_UDP_Client() override {} + + Psc::JSON get_custom_state_json() override { + auto& state = cli.state; + return VAR_JSON_1(state); + } + + concurrencpp::result handle_in_loop_coro() override { + co_await cli.tick_coro(); + co_return; + } + + concurrencpp::result send_coro(const std::string& data) override { + co_await cli.send_coro(data); + co_return; + } + + Psc::asio_socket::UDP_Client_Coro cli; + + void from_json(const Psc::JSON* that_json) override { + Data_Feed::from_json(that_json); + Data_Feed_UDP_Client_Data::from_base_json(that_json); + } + + Psc::JSON to_json() override { + return Data_Feed::to_json() += Data_Feed_UDP_Client_Data::to_base_json(); + } + + concurrencpp::result _close() override { + std::cout << "udp client target address:" << cli.dest_address.to_string() + << " closed" << std::endl; + co_await cli.close_coro(); + co_return; + } + + concurrencpp::result _open() override { + cli.create(); + cli.set_dest_address(url, port); + co_await cli.connect_coro(); + co_return; + } }; -inline std::shared_ptr -create_data_feed_from_type(const std::string& t) { - std::shared_ptr ret{}; - if (t == "Data_Feed_TCP_Server") - ret = std::make_shared(); - else if (t == "Data_Feed_UDP_Server") - ret = std::make_shared(); - else if (t == "Data_Feed_TCP_Client") - ret = std::make_shared(); - else if (t == "Data_Feed_UDP_Client") - ret = std::make_shared(); - else { - std::ostringstream oss; - oss << "unknown Data_Feed type: " << t << " " << LOG_POS_SIMPLE - << std::endl; - std::cout << oss.str(); - throw std::invalid_argument(oss.str()); - } - return ret; + +inline std::shared_ptr create_data_feed_from_type(const std::string& t) { + std::shared_ptr ret{}; + if (t == "Data_Feed_TCP_Server") + ret = std::make_shared(); + else if (t == "Data_Feed_UDP_Server") + ret = std::make_shared(); + else if (t == "Data_Feed_TCP_Client") + ret = std::make_shared(); + else if (t == "Data_Feed_UDP_Client") + ret = std::make_shared(); + else { + std::ostringstream oss; + oss << "unknown Data_Feed type: " << t << " " << LOG_POS_SIMPLE + << std::endl; + std::cout << oss.str(); + throw std::invalid_argument(oss.str()); + } + return ret; } class Data_feed_Config_Data { public: - Psc::Copyable_Atomic empty_wait_milliseconds{}; - Psc::Copyable_Atomic packet_byte_size{}; - size_t tcp_server_default_connect_user_buffer_size{}; - size_t tcp_server_default_connect_system_buffer_size{}; - PSC_USE_JSON + Psc::Copyable_Atomic empty_wait_milliseconds{}; + Psc::Copyable_Atomic packet_byte_size{}; + size_t tcp_server_default_connect_user_buffer_size{}; + size_t tcp_server_default_connect_system_buffer_size{}; + PSC_USE_JSON }; - class Data_feed_Config : public Data_feed_Config_Data { public: - Psc::String_Pool pool_ = - Psc::String_Pool(1600, 8 * 1024); // 8192 * 1600 12.5 MB - Ordered_Map> map; - Data_feed_Config() = default; - void init(const Psc::JSON* that_json) { - auto connect = that_json->get("list"); - for (auto& it : connect->children) { - auto type = it.get_string("type"); - std::shared_ptr t = create_data_feed_from_type(type); - t->from_json(&it); - map.push_back(t); - } - Data_feed_Config_Data::from_base_json(that_json); - } - Psc::JSON list() { - auto connect_json = Psc::JSON::array(); - for (auto& it : map.list()) { - connect_json.children.emplace_back(it->to_json()); - } - return connect_json; - } - Psc::JSON to_json() { - Psc::JSON ret = Data_feed_Config_Data::to_base_json(); - ret.append({"list", list()}); - return ret; - } - Psc::JSON get_feed(const std::string& key); - void server(Global* g); -}; \ No newline at end of file + Psc::String_Pool pool_ = + Psc::String_Pool(1600, 8 * 1024); // 8192 * 1600 12.5 MB + Ordered_Map> map; + Data_feed_Config() = default; + + void init(const Psc::JSON* that_json) { + auto connect = that_json->get("list"); + for (auto& it : connect->children) { + auto type = it.get_string("type"); + std::shared_ptr t = create_data_feed_from_type(type); + t->from_json(&it); + map.push_back(t); + } + Data_feed_Config_Data::from_base_json(that_json); + } + + Psc::JSON list() { + auto connect_json = Psc::JSON::array(); + for (auto& it : map.list()) { + connect_json.children.emplace_back(it->to_json()); + } + return connect_json; + } + + Psc::JSON to_json() { + Psc::JSON ret = Data_feed_Config_Data::to_base_json(); + ret.append({"list", list()}); + return ret; + } + + Psc::JSON get_feed(const std::string& key); + void server(Global* g); +}; diff --git a/module/Local_Server/Data_Source/Data_Source.cpp b/module/Local_Server/Data_Source/Data_Source.cpp index 14e030d..4cea266 100644 --- a/module/Local_Server/Data_Source/Data_Source.cpp +++ b/module/Local_Server/Data_Source/Data_Source.cpp @@ -1,633 +1,591 @@ #include "Data_Source.h" - #include - #include "../server/Global.h" #include "Database.h" -Psc::serial::Serial *create_serial(const std::string &serial_name, +Psc::serial::Serial* create_serial(const std::string& serial_name, Baud_Rate_Type baud_rate) { - auto serial = new Psc::serial::Serial; - serial->set_serial_name(serial_name); - serial->set_baud_rate(baud_rate); - serial->set_parity(Psc::serial::Parity::NoParity); - serial->set_data_bits(Psc::serial::DataBits::Data8); - serial->set_stop_bits(Psc::serial::StopBits::OneStop); - serial->set_flow_control(Psc::serial::FlowControl::HardwareControl); - serial->set_buffer_byte_size(10 * 1024); - if (!serial->open()) { - std::cerr << "createSerial " + serial_name + ":" + - std::to_string(baud_rate) + " 打开串口失败!\n"; - Psc::fail_fast(); - return nullptr; - } else { - // std::cerr << "createSerial " + serial_name + ":" + - // std::to_string(baud_rate) + " 打开串口成功!\n"; - } - return serial; + auto serial = new Psc::serial::Serial; + serial->set_serial_name(serial_name); + serial->set_baud_rate(baud_rate); + serial->set_parity(Psc::serial::Parity::NoParity); + serial->set_data_bits(Psc::serial::DataBits::Data8); + serial->set_stop_bits(Psc::serial::StopBits::OneStop); + serial->set_flow_control(Psc::serial::FlowControl::HardwareControl); + serial->set_buffer_byte_size(10 * 1024); + if (!serial->open()) { + std::cerr << "createSerial " + serial_name + ":" + + std::to_string(baud_rate) + " 打开串口失败!\n"; + Psc::fail_fast(); + return nullptr; + } + else { + // std::cerr << "createSerial " + serial_name + ":" + + // std::to_string(baud_rate) + " 打开串口成功!\n"; + } + return serial; } -std::shared_ptr create_from_json(const JSON *that_json) { - std::string type = that_json->get_string("type"); - std::shared_ptr ret = create_data_source_from_type(type); - ret->from_json(that_json); - // if (ret->enable) - // { - // ret->open(); - // } - return ret; +std::shared_ptr create_from_json(const JSON* that_json) { + std::string type = that_json->get_string("type"); + std::shared_ptr ret = create_data_source_from_type(type); + ret->from_json(that_json); + // if (ret->enable) + // { + // ret->open(); + // } + return ret; +} + +std::shared_ptr Data_Source::that() { + return shared_from_this(); } -std::shared_ptr Data_Source::that() { return shared_from_this(); } bool Data_Source::registered() const { - auto all_source = Global::instance()->mode_acs.data_source_config.map.list(); - for (auto &item : all_source) { - if (item.get() == this) { - return true; - } - } - return false; + auto all_source = Global::instance()->mode_acs.data_source_config.map.list(); + for (auto& item : all_source) { + if (item.get() == this) { + return true; + } + } + return false; } Psc::JSON Data_Source::get_state() { - Psc::JSON ret = Psc::JSON::object(); - ret.append_list(get_custom_state_json().children); - ret.append({"ds: read_speed(byte)", read_speed}); - ret.append({"ds: value_statistics(byte)", value_statistics}); - return ret; + Psc::JSON ret = Psc::JSON::object(); + ret.append_list(get_custom_state_json().children); + ret.append({"ds: read_speed(byte)", read_speed}); + ret.append({"ds: value_statistics(byte)", value_statistics}); + return ret; } Data_Source::Data_Source() { - // parse_format = std::make_shared(); - // 写入到配置文件是懒加载 其他保存时他跟着保存 - base_station.handle_when_updated = [this](SSR::HULC_Status_Message msg) { - if (this->update_form_gps) { - lat = msg.get_latitude(); - lon = msg.get_longitude(); - alt = msg.Alt; - } - }; + // parse_format = std::make_shared(); + // 写入到配置文件是懒加载 其他保存时他跟着保存 + base_station.handle_when_updated = [this](SSR::HULC_Status_Message msg) { + if (this->update_form_gps) { + lat = msg.get_latitude(); + lon = msg.get_longitude(); + alt = msg.Alt; + } + }; } std::string Data_Source::thread_key() const { - // return "Data_Source_Handle_Thread:[" + key + "]"; - return key + "_DS_HT"; + // return "Data_Source_Handle_Thread:[" + key + "]"; + return key + "_DS_HT"; } -void File_Data_Source::before_handle_msg(std::shared_ptr &msg) { - auto cur = std::dynamic_pointer_cast(msg); - if (cur != nullptr) { - auto &pre = last_prase_msg; - if (!pre) { - pre = cur; - return; - } - cur->day_num = pre->day_num; - if (cur->time() < pre->time()) { - ++cur->day_num; - } - } +void File_Data_Source::before_handle_msg(std::shared_ptr& msg) { + auto cur = std::dynamic_pointer_cast(msg); + if (cur != nullptr) { + auto& pre = last_prase_msg; + if (!pre) { + pre = cur; + return; + } + cur->day_num = pre->day_num; + if (cur->time() < pre->time()) { + ++cur->day_num; + } + } } -std::vector readLines(const std::string &path) { - std::vector lines; - - std::filesystem::path p = - std::filesystem::path((const char8_t *)path.c_str()); - - // std::filesystem::path p = std::filesystem::u8path(path); - std::ifstream istream(p); - if (!istream) { - std::cerr << "读取模拟数据源 readLines 无法打开文件:" << path << std::endl; - Psc::fail_fast(); - } - - // 将整个文件读入一个字符串 - std::stringstream stream; - stream << istream.rdbuf(); - // 使用 stringstream 按行分割内容 - std::string line; - char ch; - while (stream.get(ch)) { - if (ch == ' ') { - continue; - } - if (ch == '\r' || ch == '\n') { - if (!line.empty()) { - lines.push_back(line); - line.clear(); - } - - // if (ch == '\r') { - // stream.get(); // 吃掉 \n - // } - // if (ch == '\n') { - // stream.get(); // 吃掉 \n - // } - // 处理 \r\n 组合:如果当前是 \r,下一个是 \n,跳过它 - // if (ch == '\r' && stream.peek() == '\n') { - // stream.get(); // 吃掉 \n - // } - - } else { - line += ch; - } - if (line.size() == 1000) { - lines.push_back(line); - line.clear(); - } - } - // 最后一行如果没有换行符也处理一下 - if (!line.empty()) { - lines.push_back(line); - } - std::ostringstream oss; - oss << path + " 总行数:" + std::to_string(lines.size()) + " 有效行数:" + - std::to_string(lines.size()) + "\n" - << std::flush; - std::cout << oss.str() << std::flush; - return lines; +std::vector readLines(const std::string& path) { + std::vector lines; + std::filesystem::path p = + std::filesystem::path((const char8_t*)path.c_str()); + // std::filesystem::path p = std::filesystem::u8path(path); + std::ifstream istream(p); + if (!istream) { + std::cerr << "读取模拟数据源 readLines 无法打开文件:" << path << std::endl; + Psc::fail_fast(); + } + // 将整个文件读入一个字符串 + std::stringstream stream; + stream << istream.rdbuf(); + // 使用 stringstream 按行分割内容 + std::string line; + char ch; + while (stream.get(ch)) { + if (ch == ' ') { + continue; + } + if (ch == '\r' || ch == '\n') { + if (!line.empty()) { + lines.push_back(line); + line.clear(); + } + // if (ch == '\r') { + // stream.get(); // 吃掉 \n + // } + // if (ch == '\n') { + // stream.get(); // 吃掉 \n + // } + // 处理 \r\n 组合:如果当前是 \r,下一个是 \n,跳过它 + // if (ch == '\r' && stream.peek() == '\n') { + // stream.get(); // 吃掉 \n + // } + } + else { + line += ch; + } + if (line.size() == 1000) { + lines.push_back(line); + line.clear(); + } + } + // 最后一行如果没有换行符也处理一下 + if (!line.empty()) { + lines.push_back(line); + } + std::ostringstream oss; + oss << path + " 总行数:" + std::to_string(lines.size()) + " 有效行数:" + + std::to_string(lines.size()) + "\n" + << std::flush; + std::cout << oss.str() << std::flush; + return lines; } -std::string extractID(const std::string &logLine) { - size_t lastSpacePos = logLine.rfind(" "); // 查找最后一个空格 - if (lastSpacePos != std::string::npos) { - return logLine.substr(lastSpacePos + 1); // 从最后一个空格之后提取字符串 - } - return logLine; +std::string extractID(const std::string& logLine) { + size_t lastSpacePos = logLine.rfind(" "); // 查找最后一个空格 + if (lastSpacePos != std::string::npos) { + return logLine.substr(lastSpacePos + 1); // 从最后一个空格之后提取字符串 + } + return logLine; } -time_t convert_to_timestamp(const std::string &str) { - // 创建一个结构体 tm 来存储解析后的时间 - std::tm timeStruct = {}; - - std::istringstream ss(str); - ss >> std::get_time(&timeStruct, "%Y-%m-%d %H:%M:%S"); - if (ss.fail()) { - std::cerr << "Failed to parse time" << std::endl; - return -1; // 如果解析失败,返回 -1 - } - - // 将 tm 转换为 time_t(时间戳) - time_t timestamp = std::mktime(&timeStruct); - - if (timestamp == -1) { - std::cerr << "Failed to convert to time_t" << std::endl; - return -1; // 如果转换失败,返回 -1 - } - return timestamp; +time_t convert_to_timestamp(const std::string& str) { + // 创建一个结构体 tm 来存储解析后的时间 + std::tm timeStruct = {}; + std::istringstream ss(str); + ss >> std::get_time(&timeStruct, "%Y-%m-%d %H:%M:%S"); + if (ss.fail()) { + std::cerr << "Failed to parse time" << std::endl; + return -1; // 如果解析失败,返回 -1 + } + // 将 tm 转换为 time_t(时间戳) + time_t timestamp = std::mktime(&timeStruct); + if (timestamp == -1) { + std::cerr << "Failed to convert to time_t" << std::endl; + return -1; // 如果转换失败,返回 -1 + } + return timestamp; } -std::tuple extractID2(const std::string &logLine) { - size_t lastSpacePos = logLine.rfind(" "); // 查找最后一个空格 - time_t t = convert_to_timestamp(logLine.substr(0, 19)); - if (lastSpacePos != std::string::npos) { - return {logLine.substr(lastSpacePos + 1), - t}; // 从最后一个空格之后提取字符串 - } - return {logLine, t}; +std::tuple extractID2(const std::string& logLine) { + size_t lastSpacePos = logLine.rfind(" "); // 查找最后一个空格 + time_t t = convert_to_timestamp(logLine.substr(0, 19)); + if (lastSpacePos != std::string::npos) { + return { + logLine.substr(lastSpacePos + 1), + t + }; // 从最后一个空格之后提取字符串 + } + return {logLine, t}; } -std::string bin_format(const std::string &hex, time_t t) { - std::tm *currentTime = std::localtime(&t); - auto sec = currentTime->tm_hour * 3600 + currentTime->tm_min * 60 + - currentTime->tm_sec; - SSR::MLAT_timestamp a(sec, 0); - return create_Binary_Format_memory(hex, 0, &a); +std::string bin_format(const std::string& hex, time_t t) { + std::tm* currentTime = std::localtime(&t); + auto sec = currentTime->tm_hour * 3600 + currentTime->tm_min * 60 + + currentTime->tm_sec; + SSR::MLAT_timestamp a(sec, 0); + return create_Binary_Format_memory(hex, 0, &a); } -std::optional File_Data_Source::get_raw_line(int &ret_index) { - if (index == 0 && part_infos.empty()) { - ret_index = -1; - return std::nullopt; - } - std::optional log_info = std::nullopt; - if (index == part_infos.size()) { - if (play_mode == Play_Mode::loop) { - index = 0; - } else { - if (!have_report_play_back_all_success) { - std::ostringstream oss; - oss << SSR::get_current_date() << " " << SSR::get_current_time() - << " [进程:" << std::this_thread::get_id() << "] " - << file_path + " 全部加载成功!\n" - << std::flush; - std::cout << oss.str() << std::flush; - have_report_play_back_all_success = true; - } - ret_index = -1; - return std::nullopt; - } - } - ret_index = index + 1; - return part_infos[index++]; +std::optional File_Data_Source::get_raw_line(int& ret_index) { + if (index == 0 && part_infos.empty()) { + ret_index = -1; + return std::nullopt; + } + std::optional log_info = std::nullopt; + if (index == part_infos.size()) { + if (play_mode == Play_Mode::loop) { + index = 0; + } + else { + if (!have_report_play_back_all_success) { + std::ostringstream oss; + oss << SSR::get_current_date() << " " << SSR::get_current_time() + << " [进程:" << std::this_thread::get_id() << "] " + << file_path + " 全部加载成功!\n" + << std::flush; + std::cout << oss.str() << std::flush; + have_report_play_back_all_success = true; + } + ret_index = -1; + return std::nullopt; + } + } + ret_index = index + 1; + return part_infos[index++]; } // 1A 33 1A 1A F1 FB 87 73 7E 7F a8001d81a87543b0a80000 - -std::string get_true_from_raw_line(Data_Source *ds, File_Data_Type data_type, - int index, const std::string &log_info) { - std::string ret; - - // 2025-01-06 07:20:17 [info] dc2541e65001401a3119b2dd1c7af67132201 - if (data_type == File_Data_Type::BIN) { - return log_info; - } else if (data_type == File_Data_Type::BIN_Text) { - auto info = extractID(log_info); - ret = hex2mem(info); - } else if (data_type == File_Data_Type::AVR) { - auto [info, time] = extractID2(log_info); - ret = bin_format(info, time); - } - // 1A 33 10 01 A5 31 FB 9A 5D 8D 78 0E 47 99 08 8E 32 B0 08 BE E9 8A E6 1A 32 - // 10 01 AA 14 61 7E 5E 02 E6 0F 38 7D 87 08 1A 32 10 01 AD B5 64 F7 63 5D 78 - // 0F 9D BA 93 BA - else if (data_type == File_Data_Type::BIN_Blank_Text) { - std::string info = log_info; - std::string result = ds->last_char; - ds->last_char = ""; - for (char c : info) { - if (std::isxdigit(c)) { // 会判断字符 c 是否是十六进制数字字符 - result += c; - } else if (std::isspace(c)) { - // - } else { - std::ostringstream oss; - oss << "存在非法字符[" << c << "]: value:" << (int)c << " in:" - << log_info << LOG_POS; - server_logger->c_debug("非法字符:", {}, oss.str()); - return ""; - } - } - auto size = result.size(); - if (size % 2 != 0) { - // 保存最后一个字符 - ds->last_char = result.empty() ? "" : std::string(1, result.back()); - result.pop_back(); - } - ret = hex2mem(result); - } else if (data_type == File_Data_Type::BIN_Blank_One_Line_With_Escape) { - auto size = log_info.size(); - if (size % 2 != 0) { - return hex2mem(log_info.substr(0, size - 1)); - } - return hex2mem(log_info); - } else if (data_type == File_Data_Type::BIN_Blank_One_Line_No_Escape) { - auto size = log_info.size(); - std::string data; - if (size % 2 != 0) { - data = log_info.substr(0, size - 1); - } else { - data = log_info; - } - return SSR::packet_to_escape_format(hex2mem(data)); - } else if (data_type == File_Data_Type::SIMPLE_BIN_Blank) { - std::string info = log_info; - std::string result; - for (char c : info) { - if (c != ' ') { - result += c; - } - } - // 1 + 1 + 6 + 1 + 2/7/14 - // 1a + type time_stamp signal_level data - int size = result.size(); - if (size != 2 * 2 && size != 7 * 2 && size != 14 * 2) { - std::cout << "line_offset:[" << index << "] " << "大小" << size - << " 不为偶数,或不为2,7,14 不能转换成二进制格式:" << result - << std::endl; - return ""; - } - std::string head("\x1a"); - std::string type; - std::string time_stamp = "\x11\x22\x33\x44\x55\x66"; - std::string signal_level("\xFF"); - if (size == 2 * 2) { - type = R"(1)"; - } else if (size == 7 * 2) { - type = R"(2)"; - } else if (size == 14 * 2) { - type = R"(3)"; - } - ret = SSR::packet_to_escape_format(head + type + time_stamp + signal_level + - hex2mem(result)); - - // std::cout << ret.size() << std::endl; - } else { - std::cout << "未知的回放类型 " << static_cast(data_type) << std::endl; - Psc::fail_fast(); - } - return ret; +std::string get_true_from_raw_line(Data_Source* ds, File_Data_Type data_type, + int index, const std::string& log_info) { + std::string ret; + // 2025-01-06 07:20:17 [info] dc2541e65001401a3119b2dd1c7af67132201 + if (data_type == File_Data_Type::BIN) { + return log_info; + } + else if (data_type == File_Data_Type::BIN_Text) { + auto info = extractID(log_info); + ret = hex2mem(info); + } + else if (data_type == File_Data_Type::AVR) { + auto [info, time] = extractID2(log_info); + ret = bin_format(info, time); + } + // 1A 33 10 01 A5 31 FB 9A 5D 8D 78 0E 47 99 08 8E 32 B0 08 BE E9 8A E6 1A 32 + // 10 01 AA 14 61 7E 5E 02 E6 0F 38 7D 87 08 1A 32 10 01 AD B5 64 F7 63 5D 78 + // 0F 9D BA 93 BA + else if (data_type == File_Data_Type::BIN_Blank_Text) { + std::string info = log_info; + std::string result = ds->last_char; + ds->last_char = ""; + for (char c : info) { + if (std::isxdigit(c)) { + // 会判断字符 c 是否是十六进制数字字符 + result += c; + } + else if (std::isspace(c)) { + // + } + else { + std::ostringstream oss; + oss << "存在非法字符[" << c << "]: value:" << (int)c << " in:" + << log_info << LOG_POS; + server_logger->c_debug("非法字符:", {}, oss.str()); + return ""; + } + } + auto size = result.size(); + if (size % 2 != 0) { + // 保存最后一个字符 + ds->last_char = result.empty() ? "" : std::string(1, result.back()); + result.pop_back(); + } + ret = hex2mem(result); + } + else if (data_type == File_Data_Type::BIN_Blank_One_Line_With_Escape) { + auto size = log_info.size(); + if (size % 2 != 0) { + return hex2mem(log_info.substr(0, size - 1)); + } + return hex2mem(log_info); + } + else if (data_type == File_Data_Type::BIN_Blank_One_Line_No_Escape) { + auto size = log_info.size(); + std::string data; + if (size % 2 != 0) { + data = log_info.substr(0, size - 1); + } + else { + data = log_info; + } + return SSR::packet_to_escape_format(hex2mem(data)); + } + else if (data_type == File_Data_Type::SIMPLE_BIN_Blank) { + std::string info = log_info; + std::string result; + for (char c : info) { + if (c != ' ') { + result += c; + } + } + // 1 + 1 + 6 + 1 + 2/7/14 + // 1a + type time_stamp signal_level data + int size = result.size(); + if (size != 2 * 2 && size != 7 * 2 && size != 14 * 2) { + std::cout << "line_offset:[" << index << "] " << "大小" << size + << " 不为偶数,或不为2,7,14 不能转换成二进制格式:" << result + << std::endl; + return ""; + } + std::string head("\x1a"); + std::string type; + std::string time_stamp = "\x11\x22\x33\x44\x55\x66"; + std::string signal_level("\xFF"); + if (size == 2 * 2) { + type = R"(1)"; + } + else if (size == 7 * 2) { + type = R"(2)"; + } + else if (size == 14 * 2) { + type = R"(3)"; + } + ret = SSR::packet_to_escape_format(head + type + time_stamp + signal_level + + hex2mem(result)); + // std::cout << ret.size() << std::endl; + } + else { + std::cout << "未知的回放类型 " << static_cast(data_type) << std::endl; + Psc::fail_fast(); + } + return ret; } concurrencpp::result File_Data_Source::_close() { - std::lock_guard g(mtx); - index = 0; - part_infos.clear(); - co_return; + std::lock_guard g(mtx); + index = 0; + part_infos.clear(); + co_return; } concurrencpp::result File_Data_Source::_open() { - std::lock_guard g(mtx); - auto path = get_true_file_path(); - - namespace fs = std::filesystem; - if (!fs::exists(path)) { - state = "文件不存在"; - co_return; - } - - if (data_type == File_Data_Type::BIN) { - part_infos = readBinaryFileAsString(path, 1000); - } else { - part_infos = readLines(path); - } - state = "已加载" + to_string(part_infos.size()) + "长度数据!"; - co_return; + std::lock_guard g(mtx); + auto path = get_true_file_path(); + namespace fs = std::filesystem; + if (!fs::exists(path)) { + state = "文件不存在"; + co_return; + } + if (data_type == File_Data_Type::BIN) { + part_infos = readBinaryFileAsString(path, 1000); + } + else { + part_infos = readLines(path); + } + state = "已加载" + to_string(part_infos.size()) + "长度数据!"; + co_return; } -std::vector -File_Data_Source::readBinaryFileAsString(const std::string &filepath, - size_t part_size) { - // 打开文件(以二进制模式) - std::ifstream file(filepath, std::ios::binary); - - if (!file) { - std::cerr << "无法打开文件: " << filepath << std::endl; - return {}; // 文件打开失败,返回空vector - } - - // 获取文件大小 - file.seekg(0, std::ios::end); - size_t fileSize = file.tellg(); - file.seekg(0, std::ios::beg); - - // 存储读取的部分 - std::vector parts; - - // 读取文件的每一部分 - size_t bytesRead = 0; - while (bytesRead < fileSize) { - // 计算每个部分的长度(最后一部分可能小于part_size) - size_t remaining = fileSize - bytesRead; - size_t currentPartSize = (remaining < part_size) ? remaining : part_size; - - // 创建buffer来存储当前部分 - std::string buffer(currentPartSize, '\0'); - - // 读取当前部分 - file.read(&buffer[0], currentPartSize); - - // 将读取的部分添加到vector - parts.push_back(std::move(buffer)); - - // 更新已读取字节数 - bytesRead += currentPartSize; - } - - // 关闭文件 - file.close(); - - return parts; +std::vector File_Data_Source::readBinaryFileAsString(const std::string& filepath, + size_t part_size) { + // 打开文件(以二进制模式) + std::ifstream file(filepath, std::ios::binary); + if (!file) { + std::cerr << "无法打开文件: " << filepath << std::endl; + return {}; // 文件打开失败,返回空vector + } + // 获取文件大小 + file.seekg(0, std::ios::end); + size_t fileSize = file.tellg(); + file.seekg(0, std::ios::beg); + // 存储读取的部分 + std::vector parts; + // 读取文件的每一部分 + size_t bytesRead = 0; + while (bytesRead < fileSize) { + // 计算每个部分的长度(最后一部分可能小于part_size) + size_t remaining = fileSize - bytesRead; + size_t currentPartSize = (remaining < part_size) ? remaining : part_size; + // 创建buffer来存储当前部分 + std::string buffer(currentPartSize, '\0'); + // 读取当前部分 + file.read(&buffer[0], currentPartSize); + // 将读取的部分添加到vector + parts.push_back(std::move(buffer)); + // 更新已读取字节数 + bytesRead += currentPartSize; + } + // 关闭文件 + file.close(); + return parts; } -void File_Data_Source::origin_data_transform_mode_data(std::string &mode_data) { - std::lock_guard g(mtx); - assert(mode_data.size() == 0); - int ret_index = 0; - if (play_mode != Play_Mode::analysis) { - std::optional log_info = get_raw_line(ret_index); - mode_data = log_info.has_value() - ? get_true_from_raw_line(this, data_type, ret_index, - log_info.value()) - : ""; - } else { - int num = 0; - std::string ret; - std::optional log_info = get_raw_line(ret_index); - while (log_info.has_value()) { - num++; - auto data = log_info.value(); - auto cur = get_true_from_raw_line(this, data_type, ret_index, data); - ret += cur; - // 一定要在这个位置,否则会导致遗漏报文 - if (num == 1000) { - break; - } - log_info = get_raw_line(ret_index); - } - // std::cout << "size == " << t.size() << std::endl; - mode_data = ret; - } +void File_Data_Source::origin_data_transform_mode_data(std::string& mode_data) { + std::lock_guard g(mtx); + assert(mode_data.size() == 0); + int ret_index = 0; + if (play_mode != Play_Mode::analysis) { + std::optional log_info = get_raw_line(ret_index); + mode_data = log_info.has_value() + ? get_true_from_raw_line(this, data_type, ret_index, + log_info.value()) + : ""; + } + else { + int num = 0; + std::string ret; + std::optional log_info = get_raw_line(ret_index); + while (log_info.has_value()) { + num++; + auto data = log_info.value(); + auto cur = get_true_from_raw_line(this, data_type, ret_index, data); + ret += cur; + // 一定要在这个位置,否则会导致遗漏报文 + if (num == 1000) { + break; + } + log_info = get_raw_line(ret_index); + } + // std::cout << "size == " << t.size() << std::endl; + mode_data = ret; + } } void File_Data_Source::handle_mode_s(std::shared_ptr msg) { - if (!msg) - return; - - cache_list.push_back(std::make_shared(std::move(msg))); - - if (cache_list.empty()) - return; - if (pre_cache == nullptr) { - pre_cache = cache_list.front(); - cache_list.pop_front(); - - SSR::Play_Back_Time_Point &start = player_clock.start_time; - start.day_num = pre_cache->day_num; - start.day_sec = pre_cache->msg->mlat_timestamp.daysec; - } - - auto sys_time = player_clock.get_cur_time_point(); - while (true) { - if (cache_list.empty()) - break; - auto pre = pre_cache; - auto cur = cache_list.front(); - cur->day_num = pre->day_num; - if (cur->time() < pre->time()) { - cur->day_num++; - } - cache_list.pop_front(); - pre_cache = cur; - Data_Source::handle_mode_s(cur->msg); - if (cur->time() > sys_time) { - break; - } - } + if (!msg) + return; + cache_list.push_back(std::make_shared(std::move(msg))); + if (cache_list.empty()) + return; + if (pre_cache == nullptr) { + pre_cache = cache_list.front(); + cache_list.pop_front(); + SSR::Play_Back_Time_Point& start = player_clock.start_time; + start.day_num = pre_cache->day_num; + start.day_sec = pre_cache->msg->mlat_timestamp.daysec; + } + auto sys_time = player_clock.get_cur_time_point(); + while (true) { + if (cache_list.empty()) + break; + auto pre = pre_cache; + auto cur = cache_list.front(); + cur->day_num = pre->day_num; + if (cur->time() < pre->time()) { + cur->day_num++; + } + cache_list.pop_front(); + pre_cache = cur; + Data_Source::handle_mode_s(cur->msg); + if (cur->time() > sys_time) { + break; + } + } } -void Dll_Data_Source::origin_data_transform_mode_data(std::string &mode_data) { - auto start = std::chrono::steady_clock::now(); - - if (read_func_ptr == nullptr) - return; - - auto buf = reinterpret_cast(buffer.data()); - auto len = read_func_ptr(buf, buffer_size); - vs.update(len); - - std::string data(buf, len); - - if (data.empty()) { - auto end = std::chrono::steady_clock::now(); - auto cost = - std::chrono::duration_cast(end - start) - .count(); - // std::cout << "Dll_Data_Source::read cost: " << cost << " us\n"; - return; - } - - auto ret = get_true_from_raw_line(this, data_type, -1, data); - - auto end = std::chrono::steady_clock::now(); - auto cost = std::chrono::duration_cast(end - start) - .count(); - - // std::cout << "Dll_Data_Source::read cost: " << cost << " us\n"; - - mode_data = ret; +void Dll_Data_Source::origin_data_transform_mode_data(std::string& mode_data) { + auto start = std::chrono::steady_clock::now(); + if (read_func_ptr == nullptr) + return; + auto buf = reinterpret_cast(buffer.data()); + auto len = read_func_ptr(buf, buffer_size); + vs.update(len); + std::string data(buf, len); + if (data.empty()) { + auto end = std::chrono::steady_clock::now(); + auto cost = + std::chrono::duration_cast(end - start) + .count(); + // std::cout << "Dll_Data_Source::read cost: " << cost << " us\n"; + return; + } + auto ret = get_true_from_raw_line(this, data_type, -1, data); + auto end = std::chrono::steady_clock::now(); + auto cost = std::chrono::duration_cast(end - start) + .count(); + // std::cout << "Dll_Data_Source::read cost: " << cost << " us\n"; + mode_data = ret; } concurrencpp::result Shared_Memory_Data_Source::_open() { - sm = std::make_unique(); - sm->init(shared_memory_name, shared_memory_size); - co_return; + sm = std::make_unique(); + sm->init(shared_memory_name, shared_memory_size); + co_return; } + concurrencpp::result Shared_Memory_Data_Source::_close() { - sm.reset(); - co_return; + sm.reset(); + co_return; } void Shared_Memory_Data_Source::origin_data_transform_mode_data( - std::string &mode_data) { - auto size = sm->shm.size(); - size_t length = size; - std::string data; - data.resize(size); - - bool ok = sm->read((uint8_t *)data.data(), length); - if (!ok) { - mode_data = ""; - } - - if (length != size) { - data.resize(length); - } - if (Global::instance()->console_config.mode_s_console) { - std::cout << "read:" << data << std::endl; - } - auto ret = get_true_from_raw_line(this, data_type, -1, data); - mode_data = ret; + std::string& mode_data) { + auto size = sm->shm.size(); + size_t length = size; + std::string data; + data.resize(size); + bool ok = sm->read((uint8_t*)data.data(), length); + if (!ok) { + mode_data = ""; + } + if (length != size) { + data.resize(length); + } + if (Global::instance()->console_config.mode_s_console) { + std::cout << "read:" << data << std::endl; + } + auto ret = get_true_from_raw_line(this, data_type, -1, data); + mode_data = ret; } -void Data_Source_Config::server(Global *g) { - auto &svr = g->svr; - auto &api = g->api; - std::string name = "data_source"; - // 返回所有 JSON 数据的 API - svr.Post(api + "get_data_source_connect", [this](HTTP_Param) { - CHECK_JSON_PARAM - HTTP_REQUIRE_VALUE(key, params.try_get_string("key")) - auto t = map.get(key); - JSON ret{nullptr}; - if (t.has_value()) { - ret = t.value()->get_all_connect_feed(); - } - res->setBody(warp(ret).to_json_string()); - }); - - svr.Post(api + "get_data_source_state", [this](HTTP_Param) { - CHECK_JSON_PARAM - HTTP_REQUIRE_VALUE(key, params.try_get_string("key")) - auto t = map.get(key); - JSON ret{nullptr}; - if (t.has_value()) { - ret = t.value()->get_state(); - } - res->setBody(warp(ret).to_json_string()); - }); - - svr.Post(api + "get_mode_s_data_source_config", [this](HTTP_Param) { - res->setBody(warp(to_json()).to_json_string()); - }); - - svr.Post(api + svr.update + name, [this, g](HTTP_Param) { - CHECK_JSON_PARAM - HTTP_REQUIRE_VALUE(key, params.try_get_string("key")) - HTTP_REQUIRE_VALUE(ds, map.get(key)) - // 直接关闭 - // ds->enable = false; - // ds->close(); - ds->from_json(¶ms); - - g->save(); - g->mode_acs.source_feed_relation_config.set_need_refresh(); - }); - svr.Post(api + svr.insert + name, [g, this](HTTP_Param) { - CHECK_JSON_PARAM - - HTTP_REQUIRE_VALUE(index, params.try_get_number("index")) - HTTP_REQUIRE_PTR(data, params.get("data")) - HTTP_REQUIRE_VALUE(t, data->try_get_string("type")) - std::cout << params.to_json_string() << std::endl; - std::shared_ptr ds = create_data_source_from_type(t); - ds->from_json(data); - HTTP_REQUIRE_VALUE(enable, data->try_get_bool("enable")) - (void)enable; - - HTTP_REQUIRE_TRUE(map.insert(index, ds), "index") - - // std::cout << params.to_json_string() << std::endl; - g->mode_acs.source_feed_relation_config.set_need_refresh(); - Config::save(); - res->setBody(warp(to_json()).to_json_string()); - }); - - svr.Post(api + svr.remove + name, [g, this](HTTP_Param) { - CHECK_JSON_PARAM - HTTP_REQUIRE_VALUE(index, params.try_get_number("index")) - HTTP_REQUIRE_VALUE(ds, map.try_get(index)) - ds->async_stop(); - HTTP_REQUIRE_TRUE(map.remove(index), "index") - g->save(); - res->setBody(warp(to_json()).to_json_string()); - g->mode_acs.source_feed_relation_config.set_need_refresh(); - }); - - svr.Post(api + svr.rise + name, [g, this](HTTP_Param) { - CHECK_JSON_PARAM - HTTP_REQUIRE_VALUE(index, params.try_get_number("index")) - HTTP_REQUIRE_TRUE(map.swap(index, index - 1), "index") - g->save(); - res->setBody(warp(to_json()).to_json_string()); - g->mode_acs.source_feed_relation_config.set_need_refresh(); - }); - svr.Post(api + svr.fall + name, [g, this](HTTP_Param) { - CHECK_JSON_PARAM - HTTP_REQUIRE_VALUE(index, params.try_get_number("index")) - HTTP_REQUIRE_TRUE(map.swap(index, index + 1), "index") - g->save(); - res->setBody(warp(to_json()).to_json_string()); - g->mode_acs.source_feed_relation_config.set_need_refresh(); - }); +void Data_Source_Config::server(Global* g) { + auto& svr = g->svr; + auto& api = g->api; + std::string name = "data_source"; + // 返回所有 JSON 数据的 API + svr.Post(api + "get_data_source_connect", [this](HTTP_Param) { + CHECK_JSON_PARAM + HTTP_REQUIRE_VALUE(key, params.try_get_string("key")) + auto t = map.get(key); + JSON ret{nullptr}; + if (t.has_value()) { + ret = t.value()->get_all_connect_feed(); + } + res->setBody(warp(ret).to_json_string()); + }); + svr.Post(api + "get_data_source_state", [this](HTTP_Param) { + CHECK_JSON_PARAM + HTTP_REQUIRE_VALUE(key, params.try_get_string("key")) + auto t = map.get(key); + JSON ret{nullptr}; + if (t.has_value()) { + ret = t.value()->get_state(); + } + res->setBody(warp(ret).to_json_string()); + }); + svr.Post(api + "get_mode_s_data_source_config", [this](HTTP_Param) { + res->setBody(warp(to_json()).to_json_string()); + }); + svr.Post(api + svr.update + name, [this, g](HTTP_Param) { + CHECK_JSON_PARAM + HTTP_REQUIRE_VALUE(key, params.try_get_string("key")) + HTTP_REQUIRE_VALUE(ds, map.get(key)) + // 直接关闭 + // ds->enable = false; + // ds->close(); + ds->from_json(¶ms); + g->save(); + g->mode_acs.source_feed_relation_config.set_need_refresh(); + }); + svr.Post(api + svr.insert + name, [g, this](HTTP_Param) { + CHECK_JSON_PARAM + HTTP_REQUIRE_VALUE(index, params.try_get_number("index")) + HTTP_REQUIRE_PTR(data, params.get("data")) + HTTP_REQUIRE_VALUE(t, data->try_get_string("type")) + std::cout << params.to_json_string() << std::endl; + std::shared_ptr ds = create_data_source_from_type(t); + ds->from_json(data); + HTTP_REQUIRE_VALUE(enable, data->try_get_bool("enable")) + (void)enable; + HTTP_REQUIRE_TRUE(map.insert(index, ds), "index") + // std::cout << params.to_json_string() << std::endl; + g->mode_acs.source_feed_relation_config.set_need_refresh(); + Config::save(); + res->setBody(warp(to_json()).to_json_string()); + }); + svr.Post(api + svr.remove + name, [g, this](HTTP_Param) { + CHECK_JSON_PARAM + HTTP_REQUIRE_VALUE(index, params.try_get_number("index")) + HTTP_REQUIRE_VALUE(ds, map.try_get(index)) + ds->async_stop(); + HTTP_REQUIRE_TRUE(map.remove(index), "index") + g->save(); + res->setBody(warp(to_json()).to_json_string()); + g->mode_acs.source_feed_relation_config.set_need_refresh(); + }); + svr.Post(api + svr.rise + name, [g, this](HTTP_Param) { + CHECK_JSON_PARAM + HTTP_REQUIRE_VALUE(index, params.try_get_number("index")) + HTTP_REQUIRE_TRUE(map.swap(index, index - 1), "index") + g->save(); + res->setBody(warp(to_json()).to_json_string()); + g->mode_acs.source_feed_relation_config.set_need_refresh(); + }); + svr.Post(api + svr.fall + name, [g, this](HTTP_Param) { + CHECK_JSON_PARAM + HTTP_REQUIRE_VALUE(index, params.try_get_number("index")) + HTTP_REQUIRE_TRUE(map.swap(index, index + 1), "index") + g->save(); + res->setBody(warp(to_json()).to_json_string()); + g->mode_acs.source_feed_relation_config.set_need_refresh(); + }); } -concurrencpp::result Data_Source::loop_coro( - std::shared_ptr executor_) { - auto source = this; - co_await concurrencpp::resume_on(executor_); - while (enable) { - if (!source->running() || !source->registered()) { - break; - } - co_await source->handle_in_loop_coro(); - auto mode_data = co_await source->read_coro(); - if (!enable || !source->running() || !source->registered()) { - break; - } - source->process_mode_acs_data(mode_data); - co_await concurrencpp::resume_on(executor_); - } - co_return; -} + + diff --git a/module/Local_Server/Data_Source/Data_Source.h b/module/Local_Server/Data_Source/Data_Source.h index f0c2e41..a01a55a 100644 --- a/module/Local_Server/Data_Source/Data_Source.h +++ b/module/Local_Server/Data_Source/Data_Source.h @@ -73,20 +73,15 @@ class Data_Source : public std::enable_shared_from_this, public Data_Source_Handler, public Data_Source_Data { public: std::shared_ptr that(); - virtual concurrencpp::result read_coro() { - co_return ""; - }; + virtual concurrencpp::result read_coro() {co_return "";} bool registered() const; virtual Psc::JSON get_custom_state_json() = 0; Psc::JSON get_state(); std::string last_char; // 用于处理奇数字节 Data_Source(); - concurrencpp::result loop_coro( - std::shared_ptr executor) override; + concurrencpp::result loop_coro() final; std::shared_ptr last_prase_msg = nullptr; - virtual concurrencpp::result handle_in_loop_coro() { - co_return; - } + virtual concurrencpp::result handle_in_loop_coro() { co_return;} Frequency_Limit statistic_fl; std::string thread_key() const; Psc::JSON statistic_json() { diff --git a/module/Local_Server/Data_Source/Data_Source_Handler.cpp b/module/Local_Server/Data_Source/Data_Source_Handler.cpp index 292ff57..9d1981d 100644 --- a/module/Local_Server/Data_Source/Data_Source_Handler.cpp +++ b/module/Local_Server/Data_Source/Data_Source_Handler.cpp @@ -3,577 +3,558 @@ #include "Local_Server/server/Global.h" using namespace Psc; -std::shared_ptr ds(Data_Source_Handler *dsh) { - return dynamic_cast(dsh)->that(); +std::shared_ptr ds(Data_Source_Handler* dsh) { + return dynamic_cast(dsh)->that(); } -std::shared_ptr -Data_Source_Handler::create_msg(const std::string &packet) { - - auto source = ds(this); - if (packet[0] != 0x1a) { - std::cout << "first:" << mem2hex(packet) << std::endl; - return nullptr; - } - - std::string error_len = source->key + " " + LOG_POS_SIMPLE + - std::string(" ") + "mode_s_error_length"; - if (packet.size() < 2) - return nullptr; - auto mt = packet[1]; - if (mt == SSR::Msg::AC) { - if (packet.size() != SSR::Msg::AC_len) { - SSR::mode_s_logger->c_debug( - error_len, {}, - std::to_string(mt) + " size:" + std::to_string(packet.size()) + - " hex:" + mem2hex(packet) + - " should:" + std::to_string(SSR::Msg::AC_len)); - mode_ac_statistic.add_length_error(); - return nullptr; - } - mode_ac_statistic.add(); - return std::make_shared(source, packet); - } - if (mt == SSR::Msg::S7) { - if (packet.size() != SSR::Mode_S_Msg::S7_len) { - SSR::mode_s_logger->c_debug( - error_len, {}, - std::to_string(mt) + " size:" + std::to_string(packet.size()) + - " hex:" + mem2hex(packet) + - " should:" + std::to_string(SSR::Msg::S7_len)); - mode_s_statistic.add_length_error( - "[length error] Msg::S7 handle_mode_s_source"); - return nullptr; - } - return std::make_shared(source, packet); - } - - if (mt == SSR::Msg::S14) { - if (packet.size() != SSR::Msg::S14_len) { - SSR::mode_s_logger->c_debug( - error_len, {}, - std::to_string(mt) + " size:" + std::to_string(packet.size()) + - " hex:" + mem2hex(packet) + - " should:" + std::to_string(SSR::Msg::S14_len)); - mode_s_statistic.add_length_error( - "[length error] Msg::S14 handle_mode_s_source"); - return nullptr; - } - return std::make_shared(source, packet); - } - - if (mt == SSR::Msg::Radarcape_status) { - return nullptr; // 不知道如何解析跳过 - if (packet.size() != SSR::Msg::Radarcape_status_len) { - SSR::mode_s_logger->c_debug( - error_len, {}, - std::to_string(mt) + " size:" + std::to_string(packet.size()) + - " hex:" + mem2hex(packet) + - " should:" + std::to_string(SSR::Msg::Radarcape_status_len)); - mode_s_statistic.add_length_error( - "[length error] Msg::Radarcape_status_len handle_mode_s_source"); - return nullptr; - } - return std::make_shared(source, packet); - } - - if (mt == SSR::Msg::HULC_Status) { - if (packet.size() != SSR::Msg::HULC_len) { - - // 找不到协议 size:23 hex:1A34195F0000001500B502FF06F423CE50000090000000 - // should:5 - SSR::mode_s_logger->c_debug( - error_len, {}, - Psc::to_string(source->type) + " HULC size:" + - std::to_string(packet.size()) + " hex:" + mem2hex(packet)); - return nullptr; - } - return std::make_shared(source, packet); - } - // std::cout << "unknown_type:" << memory2hex(packet); - rotating_log("unknown_type", mem2hex(packet)); - return nullptr; +std::shared_ptr Data_Source_Handler::create_msg(const std::string& packet) { + auto source = ds(this); + if (packet[0] != 0x1a) { + std::cout << "first:" << mem2hex(packet) << std::endl; + return nullptr; + } + std::string error_len = source->key + " " + LOG_POS_SIMPLE + + std::string(" ") + "mode_s_error_length"; + if (packet.size() < 2) + return nullptr; + auto mt = packet[1]; + if (mt == SSR::Msg::AC) { + if (packet.size() != SSR::Msg::AC_len) { + SSR::mode_s_logger->c_debug( + error_len, {}, + std::to_string(mt) + " size:" + std::to_string(packet.size()) + + " hex:" + mem2hex(packet) + + " should:" + std::to_string(SSR::Msg::AC_len)); + mode_ac_statistic.add_length_error(); + return nullptr; + } + mode_ac_statistic.add(); + return std::make_shared(source, packet); + } + if (mt == SSR::Msg::S7) { + if (packet.size() != SSR::Mode_S_Msg::S7_len) { + SSR::mode_s_logger->c_debug( + error_len, {}, + std::to_string(mt) + " size:" + std::to_string(packet.size()) + + " hex:" + mem2hex(packet) + + " should:" + std::to_string(SSR::Msg::S7_len)); + mode_s_statistic.add_length_error( + "[length error] Msg::S7 handle_mode_s_source"); + return nullptr; + } + return std::make_shared(source, packet); + } + if (mt == SSR::Msg::S14) { + if (packet.size() != SSR::Msg::S14_len) { + SSR::mode_s_logger->c_debug( + error_len, {}, + std::to_string(mt) + " size:" + std::to_string(packet.size()) + + " hex:" + mem2hex(packet) + + " should:" + std::to_string(SSR::Msg::S14_len)); + mode_s_statistic.add_length_error( + "[length error] Msg::S14 handle_mode_s_source"); + return nullptr; + } + return std::make_shared(source, packet); + } + if (mt == SSR::Msg::Radarcape_status) { + return nullptr; // 不知道如何解析跳过 + if (packet.size() != SSR::Msg::Radarcape_status_len) { + SSR::mode_s_logger->c_debug( + error_len, {}, + std::to_string(mt) + " size:" + std::to_string(packet.size()) + + " hex:" + mem2hex(packet) + + " should:" + std::to_string(SSR::Msg::Radarcape_status_len)); + mode_s_statistic.add_length_error( + "[length error] Msg::Radarcape_status_len handle_mode_s_source"); + return nullptr; + } + return std::make_shared(source, packet); + } + if (mt == SSR::Msg::HULC_Status) { + if (packet.size() != SSR::Msg::HULC_len) { + // 找不到协议 size:23 hex:1A34195F0000001500B502FF06F423CE50000090000000 + // should:5 + SSR::mode_s_logger->c_debug( + error_len, {}, + Psc::to_string(source->type) + " HULC size:" + + std::to_string(packet.size()) + " hex:" + mem2hex(packet)); + return nullptr; + } + return std::make_shared(source, packet); + } + // std::cout << "unknown_type:" << memory2hex(packet); + rotating_log("unknown_type", mem2hex(packet)); + return nullptr; } -void Data_Source_Handler::process_mode_acs_data( - const std::string &origin_data) { - // 先读取原始数据 注意多复制了一遍 - auto mode_data = origin_data; - origin_data_transform_mode_data(mode_data); - - if (mode_data.empty()) { - std::this_thread::sleep_for(std::chrono::milliseconds(10)); - } - - auto source = ds(this); - auto size = mode_data.size(); - read_speed.update(size); - value_statistics.update(size); - - // 预处理数据 - static bool mode_s_console = - Global::instance()->console_config.mode_s_console; - static bool record_playback = - Global::instance()->console_config.record_playback; - - if (mode_data.empty()) - return; - if (record_playback) { - pure_log(get_exe_dir() + "/playback/" + source->key + "_playback.dat", - mem2hex(mode_data, true, " ") + "\n"); - } - if (mode_s_console) { - std::cout << source->key + " read:[mode_s_serial]:" << mem2hex(mode_data) - << std::endl; - } - - SSR::Binary_Format_handle_buffer( - source->buffer, mode_data, [this, source](std::string &packet) { - auto msg = create_msg(packet); - if (!msg) - return; - source->push_to_feed(msg); - auto mt = msg->type; - bool mode_s = mt == SSR::Msg::S7 || mt == SSR::Msg::S14; - if (mt == SSR::Msg::HULC_Status) { - source->handle_HULC(packet); - } else if (mt == SSR::Msg::Radarcape_status) { - auto radarcape_msg = SSR::create_Radarcape_STATUS_Message(packet); - std::cout << radarcape_msg.toJson().to_json_string() << std::endl; - SSR::mode_s_logger->debug("Radarcape_status/radarcape", {}, - radarcape_msg.toJson().to_json_string()); - } else if (mode_s) { - // 拓展点 - handle_mode_s(std::dynamic_pointer_cast(msg)); - } - }); +size_t Data_Source_Handler::process_mode_acs_data(const std::string& origin_data) { + // 先读取原始数据 注意多复制了一遍 + auto mode_data = origin_data; + origin_data_transform_mode_data(mode_data); + size_t ret = 0; + if (mode_data.empty()) { + return ret; + } + auto source = ds(this); + auto size = mode_data.size(); + read_speed.update(size); + value_statistics.update(size); + // 预处理数据 + static bool mode_s_console = Global::instance()->console_config.mode_s_console; + static bool record_playback = Global::instance()->console_config.record_playback; + if (record_playback) { + pure_log(get_exe_dir() + "/playback/" + source->key + "_playback.dat", + mem2hex(mode_data, true, " ") + "\n"); + } + if (mode_s_console) { + std::cout << source->key + " read:[mode_s_serial]:" << mem2hex(mode_data) + << std::endl; + } + SSR::Binary_Format_handle_buffer( + source->buffer, mode_data, [this, source, &ret](std::string& packet) { + ret++; + auto msg = create_msg(packet); + if (!msg) + return; + source->push_to_feed(msg); + auto mt = msg->type; + bool mode_s = mt == SSR::Msg::S7 || mt == SSR::Msg::S14; + if (mt == SSR::Msg::HULC_Status) { + source->handle_HULC(packet); + } + else if (mt == SSR::Msg::Radarcape_status) { + auto radarcape_msg = SSR::create_Radarcape_STATUS_Message(packet); + std::cout << radarcape_msg.toJson().to_json_string() << std::endl; + SSR::mode_s_logger->debug("Radarcape_status/radarcape", {}, + radarcape_msg.toJson().to_json_string()); + } + else if (mode_s) { + // 拓展点 + handle_mode_s(std::dynamic_pointer_cast(msg)); + } + }); + return ret; } -void Data_Source_Handler::handle_mode_s( - std::shared_ptr mode_s_msg) { - auto source = ds(this); - std::string t = mode_s_msg->mlat_timestamp.to_memory() + - mode_s_msg->signal_level + Psc::hex2mem(mode_s_msg->msg_hex); - auto p = mode_s_msg->packet.substr(2); - if (t != p) { - std::cout << mem2hex(t, true, " ") << std::endl; - std::cout << mem2hex(mode_s_msg->packet, true, " ") << std::endl; - std::cout << VAR_STR_2(t, mode_s_msg->packet) << std::endl; - } - - // TODO: 可能不需要push_to_feed - source->push_to_feed(mode_s_msg); - auto &cfg = Global::instance()->mode_acs; - - SSR::parse_mode_s_bin(source.get(), mode_s_msg, - source->base_station.get_pos(), cfg.max_speed_m_s, - cfg.air_pos_timeout, cfg.surface_pos_timeout); - - auto base = source->get_aircraft(mode_s_msg->icao); - - if (base) { - auto derived = std::dynamic_pointer_cast(base); - derived->refresh_external_database_info(); - } - - if (Global::instance()->mlat.merge) { - auto &mh = Global::instance()->mlat_handler; - mh.push(mode_s_msg); - auto tt = mh.get_all(); - if (!tt.empty()) { - pure_log("@/logs/mlat.log", - "receive[" + std::to_string(tt.size()) + "]:\n"); - for (Mlat_MSG &t : tt) { - std::ostringstream oss; - oss << std::fixed << std::setprecision(10); - oss << "===================================================\n"; - int n = static_cast(t.size()); - auto icao = t.icao().value_or("null"); - oss << "\tmlat_msg:" << n; - oss << "\ticao:" << icao; - oss << "\thex:" << t.msg_hex() << std::endl; - - bool have_pos = false; - if (icao != "null") { - auto air = source->get_aircraft(icao); - if (air != nullptr) { - auto callsign = air->bds20_call_sign(); - oss << "\tcall_sign:" << callsign.value_or("null") << std::endl; - auto o_pos = air->pos(); - auto o_alt = air->altitude_meter(); - if (o_pos.has_value() && o_alt.has_value()) { - have_pos = true; - auto pos = o_pos.value(); - source->alt = o_alt.value(); - double x, y, z; - SSR::CPR::WGS84_LBH_to_XYZ(pos.lon, pos.lat, source->alt, x, y, - z); - oss << "\tpos:[" << pos.lon << "," << pos.lat << "," - << source->alt << "]" << std::endl; - oss << "\tXYZ:[" << x << "," << y << "," << z << "]" - << std::endl; - } - } - } - for (int i = 0; i < t.size(); i++) { - auto &msg = t.list[i]; - oss << "\t\tds:" << msg->source->get_key(); - oss << "\ttime:" << msg->mlat_timestamp.to_string() << std::endl; - } - // if (have_pos) { - // std::cout << oss.str() << std::endl; - pure_log("@/logs/mlat.log", oss.str()); - // } - // if (t.size() > 3 && have_pos && icao == "78139F") { - // size_t i = 1; - // auto range = hex_mlat_map.equal_range(t.msg_hex()); - // // 遍历与key_to_find对应的所有元素 - // for (auto it = range.first; it != range.second; ++it) { - // oss << "\t" << i++ << " " << it->second.msg << std::endl; - // } - // oss << "===================================================\n"; - // std::cout << oss.str() << std::endl; - // pure_log("@/logs/icao/" + icao + "_mlat.log", oss.str(), true); - // } - } - } - } +void Data_Source_Handler::handle_mode_s(std::shared_ptr mode_s_msg) { + auto source = ds(this); + std::string t = mode_s_msg->mlat_timestamp.to_memory() + + mode_s_msg->signal_level + Psc::hex2mem(mode_s_msg->msg_hex); + auto p = mode_s_msg->packet.substr(2); + if (t != p) { + std::cout << mem2hex(t, true, " ") << std::endl; + std::cout << mem2hex(mode_s_msg->packet, true, " ") << std::endl; + std::cout << VAR_STR_2(t, mode_s_msg->packet) << std::endl; + } + source->push_to_feed(mode_s_msg); + auto& cfg = Global::instance()->mode_acs; + SSR::parse_mode_s_bin(source.get(), mode_s_msg, + source->base_station.get_pos(), cfg.max_speed_m_s, + cfg.air_pos_timeout, cfg.surface_pos_timeout); + auto base = source->get_aircraft(mode_s_msg->icao); + if (base) { + auto derived = std::dynamic_pointer_cast(base); + derived->refresh_external_database_info(); + } + if (Global::instance()->mlat.merge) { + auto& mh = Global::instance()->mlat_handler; + mh.push(mode_s_msg); + auto tt = mh.get_all(); + if (!tt.empty()) { + pure_log("@/logs/mlat.log", + "receive[" + std::to_string(tt.size()) + "]:\n"); + for (Mlat_MSG& t : tt) { + std::ostringstream oss; + oss << std::fixed << std::setprecision(10); + oss << "===================================================\n"; + int n = static_cast(t.size()); + auto icao = t.icao().value_or("null"); + oss << "\tmlat_msg:" << n; + oss << "\ticao:" << icao; + oss << "\thex:" << t.msg_hex() << std::endl; + bool have_pos = false; + if (icao != "null") { + auto air = source->get_aircraft(icao); + if (air != nullptr) { + auto callsign = air->bds20_call_sign(); + oss << "\tcall_sign:" << callsign.value_or("null") << std::endl; + auto o_pos = air->pos(); + auto o_alt = air->altitude_meter(); + if (o_pos.has_value() && o_alt.has_value()) { + have_pos = true; + auto pos = o_pos.value(); + source->alt = o_alt.value(); + double x, y, z; + SSR::CPR::WGS84_LBH_to_XYZ(pos.lon, pos.lat, source->alt, x, y, + z); + oss << "\tpos:[" << pos.lon << "," << pos.lat << "," + << source->alt << "]" << std::endl; + oss << "\tXYZ:[" << x << "," << y << "," << z << "]" + << std::endl; + } + } + } + for (int i = 0; i < t.size(); i++) { + auto& msg = t.list[i]; + oss << "\t\tds:" << msg->source->get_key(); + oss << "\ttime:" << msg->mlat_timestamp.to_string() << std::endl; + } + // if (have_pos) { + // std::cout << oss.str() << std::endl; + pure_log("@/logs/mlat.log", oss.str()); + // } + // if (t.size() > 3 && have_pos && icao == "78139F") { + // size_t i = 1; + // auto range = hex_mlat_map.equal_range(t.msg_hex()); + // // 遍历与key_to_find对应的所有元素 + // for (auto it = range.first; it != range.second; ++it) { + // oss << "\t" << i++ << " " << it->second.msg << std::endl; + // } + // oss << "===================================================\n"; + // std::cout << oss.str() << std::endl; + // pure_log("@/logs/icao/" + icao + "_mlat.log", oss.str(), true); + // } + } + } + } } -void Data_Source_Handler::handle_HULC(const std::string &packet) { - std::uint8_t len = SSR::get_len(packet); - std::uint8_t id = SSR::get_id(packet); - auto msg = mem2hex(packet); - - if (len != packet.size() - 4) { - SSR::mode_s_logger->debug("HULC/error_length", {}, - "需要: " + std::to_string(len) + - " 当前: " + std::to_string(packet.size()) + - " hex: " + mem2hex(packet)); - return; - } - if (id == 1) { - // 状态消息 - auto status_msg = SSR::create_HULC_Status_Message(packet); - bool gps_ok = status_msg.GPS_device_detected() && status_msg.GPS_valid() && - status_msg.GPS_has_valid_fix(); - if (gps_ok) { - } - auto g = Global::instance(); - base_station.set_msg(status_msg); - Log_Type type({}, {{"msg", msg}}); - SSR::mode_s_logger->debug("HULC/status", type, - status_msg.toJson().to_json_string()); - if (gps_ok) { - } - } else if (id == 24) { - SSR::mode_s_logger->debug("HULC/reply", {}, msg); - } else { - SSR::mode_s_logger->debug("HULC/unknown_id", {}, msg); - } +void Data_Source_Handler::handle_HULC(const std::string& packet) { + std::uint8_t len = SSR::get_len(packet); + std::uint8_t id = SSR::get_id(packet); + auto msg = mem2hex(packet); + if (len != packet.size() - 4) { + SSR::mode_s_logger->debug("HULC/error_length", {}, + "需要: " + std::to_string(len) + + " 当前: " + std::to_string(packet.size()) + + " hex: " + mem2hex(packet)); + return; + } + if (id == 1) { + // 状态消息 + auto status_msg = SSR::create_HULC_Status_Message(packet); + bool gps_ok = status_msg.GPS_device_detected() && status_msg.GPS_valid() && + status_msg.GPS_has_valid_fix(); + if (gps_ok) {} + auto g = Global::instance(); + base_station.set_msg(status_msg); + Log_Type type({}, {{"msg", msg}}); + SSR::mode_s_logger->debug("HULC/status", type, + status_msg.toJson().to_json_string()); + if (gps_ok) {} + } + else if (id == 24) { + SSR::mode_s_logger->debug("HULC/reply", {}, msg); + } + else { + SSR::mode_s_logger->debug("HULC/unknown_id", {}, msg); + } } void Data_Source_Handler::refresh_data_feed_key_list() { - // std::cout << key << " refresh_data_feed_key_list" << std::endl; - std::vector tmp; - for (auto &relation : - Global::instance()->mode_acs.source_feed_relation_config.map.list()) { - if (!relation->enable) - continue; - if (relation->type == "One_to_One_Relation") { - auto t = dynamic_cast(relation.get()); - - // std::cout << VAR_STR_2(t->source_key, this->key) << " - // refresh_data_feed_key_list" << std::endl; - if (t->source_key == this->key) { - tmp.push_back(t->feed_key); - } - } else if (relation->type == "First_Source_To_All_Feed_Relation") { - auto t = - dynamic_cast(relation.get()); - std::shared_ptr first = nullptr; - for (const auto &ds : - Global::instance()->mode_acs.data_source_config.map.list()) { - if (ds->enable) { - first = ds; - break; - } - } - if (first->key == key) { - for (const auto &df : - Global::instance()->mode_acs.data_feed_config.map.list()) { - if (df->enable) { - tmp.push_back(df->key); - } - } - } - } - - std::sort(tmp.begin(), tmp.end()); - // 去重 - auto last = std::unique(tmp.begin(), tmp.end()); - tmp.erase(last, tmp.end()); - - { - std::vector tmp_info; - - // 创建 tmp_info 向量,将 tmp 的内容转化为 Cached_Source_Info 对象 - for (const auto &key : tmp) { - tmp_info.push_back({key}); - } - - { - // 进入临界区,锁住 mutex,确保线程安全 - std::lock_guard lock(cdf_mtx); - - // 1. 删除 tmp 中没有的 cached_data_feed_key_list 元素 - auto it = cached_data_feed_key_list.begin(); - while (it != cached_data_feed_key_list.end()) { - if (std::find_if(tmp_info.begin(), tmp_info.end(), - [&](const Cached_Source_Info &info) { - return info.key == it->key; - }) == tmp_info.end()) { - // 如果当前元素在 tmp 中找不到,删除它 - it = cached_data_feed_key_list.erase(it); - } else { - ++it; - } - } - - // 2. 创建 tmp 中有但 cached_data_feed_key_list 没有的元素 - for (const auto &tmp_item : tmp_info) { - auto found = std::find_if(cached_data_feed_key_list.begin(), - cached_data_feed_key_list.end(), - [&](const Cached_Source_Info &cached_item) { - return cached_item.key == tmp_item.key; - }); - if (found == cached_data_feed_key_list.end()) { - // 如果 tmp_item 不在 cached_data_feed_key_list 中,添加它 - cached_data_feed_key_list.push_back(tmp_item); - } - } - } - } - } + // std::cout << key << " refresh_data_feed_key_list" << std::endl; + std::vector tmp; + for (auto& relation : + Global::instance()->mode_acs.source_feed_relation_config.map.list()) { + if (!relation->enable) + continue; + if (relation->type == "One_to_One_Relation") { + auto t = dynamic_cast(relation.get()); + // std::cout << VAR_STR_2(t->source_key, this->key) << " + // refresh_data_feed_key_list" << std::endl; + if (t->source_key == this->key) { + tmp.push_back(t->feed_key); + } + } + else if (relation->type == "First_Source_To_All_Feed_Relation") { + auto t = + dynamic_cast(relation.get()); + std::shared_ptr first = nullptr; + for (const auto& ds : + Global::instance()->mode_acs.data_source_config.map.list()) { + if (ds->enable) { + first = ds; + break; + } + } + if (first->key == key) { + for (const auto& df : + Global::instance()->mode_acs.data_feed_config.map.list()) { + if (df->enable) { + tmp.push_back(df->key); + } + } + } + } + std::sort(tmp.begin(), tmp.end()); + // 去重 + auto last = std::unique(tmp.begin(), tmp.end()); + tmp.erase(last, tmp.end()); + { + std::vector tmp_info; + // 创建 tmp_info 向量,将 tmp 的内容转化为 Cached_Source_Info 对象 + for (const auto& key : tmp) { + tmp_info.push_back({key}); + } + { + // 进入临界区,锁住 mutex,确保线程安全 + std::lock_guard lock(cdf_mtx); + // 1. 删除 tmp 中没有的 cached_data_feed_key_list 元素 + auto it = cached_data_feed_key_list.begin(); + while (it != cached_data_feed_key_list.end()) { + if (std::find_if(tmp_info.begin(), tmp_info.end(), + [&](const Cached_Source_Info& info) { + return info.key == it->key; + }) == tmp_info.end()) { + // 如果当前元素在 tmp 中找不到,删除它 + it = cached_data_feed_key_list.erase(it); + } + else { + ++it; + } + } + // 2. 创建 tmp 中有但 cached_data_feed_key_list 没有的元素 + for (const auto& tmp_item : tmp_info) { + auto found = std::find_if(cached_data_feed_key_list.begin(), + cached_data_feed_key_list.end(), + [&](const Cached_Source_Info& cached_item) { + return cached_item.key == tmp_item.key; + }); + if (found == cached_data_feed_key_list.end()) { + // 如果 tmp_item 不在 cached_data_feed_key_list 中,添加它 + cached_data_feed_key_list.push_back(tmp_item); + } + } + } + } + } } -std::optional -convert_to_send_format(Data_Source_Handler *ds, - const std::shared_ptr &feed, - const std::shared_ptr &msg) { - auto &type = msg->type; - auto fs = dynamic_cast(msg->source.get()); - if (fs) { - if (fs->play_mode == Play_Mode::analysis) { - // std::cout << fs->key << " analysis i ==" << i << std::endl; - } - } - // 出口输出的条件 - auto &output_format = feed->output_format.type; - auto &use_mode_ac = feed->output_format.use_mode_ac; - auto &use_status = feed->output_format.use_status; - auto &mode_s_output_type = feed->output_format.mode_s_output_type; - // 计算出是否输出消息 - std::optional send_msg = std::nullopt; - if (type == SSR::Msg::HULC_Status) { - if (!use_status) - return std::nullopt; - auto data = static_cast(msg.get()); - if (output_format == Output_Data_Format::BIN || - output_format == Output_Data_Format::BIN_ID) { - send_msg = SSR::packet_to_escape_format(data->packet); - } - } else if (type == SSR::Msg::Radarcape_status) { - auto data = static_cast(msg.get()); - if (output_format == Output_Data_Format::BIN || - output_format == Output_Data_Format::BIN_ID) { - send_msg = SSR::packet_to_escape_format(data->packet); - } - } else if (type == SSR::Msg::AC) { - if (!use_mode_ac) - return std::nullopt; - auto data = static_cast(msg.get()); - std::string &msg_hex = data->msg_hex; - char signal_level = data->signal_level; - SSR::MLAT_timestamp &mlat_timestamp = data->mlat_timestamp; - if (output_format == Output_Data_Format::BIN) { - // send_msg = create_Binary_Format_memory(msg_hex, signal_level, - // &mlat_timestamp); - send_msg = SSR::packet_to_escape_format(msg->packet); - } else if (output_format == Output_Data_Format::BIN_ID) { - // std::uint32_t id; - // { - // id = Global::instance()->mlat_server.id; - // } - // auto bin_id_packet = mode_s_msg_packet_to_server_packet(id, - // data->packet); send_msg = packet_to_escape_format(bin_id_packet); - } else if (output_format == Output_Data_Format::AVR) { - send_msg = SSR::create_AVR_format(msg_hex); - } else if (output_format == Output_Data_Format::AVR_MLAT) { - send_msg = create_MLAT_AVR_format(msg_hex, &mlat_timestamp); - } - } else if (type == SSR::Msg::S7 || type == SSR::Msg::S14) { - auto s_msg = static_cast(msg.get()); - std::string &icao = s_msg->icao; - SSR::Downlink_Format &df = s_msg->df; - std::string &msg_hex = s_msg->msg_hex; - auto &signal_level = s_msg->signal_level; - SSR::MLAT_timestamp &mlat_timestamp = s_msg->mlat_timestamp; - auto aircraft = ds->get_aircraft(s_msg->icao); - - if (output_format == Output_Data_Format::SBS) { - bool sbs_out_put = false; - if (feed->output_format.sbs_only_pos) { - auto s = ds->get_aircraft(s_msg->icao); - if (s) { - auto pos = s->pos(); - if (pos.has_value()) { - if (feed->sbs_flm.test(s_msg->icao)) { - sbs_out_put = true; - } - } - } - } else { - if (feed->sbs_flm.test(s_msg->icao)) { - sbs_out_put = true; - } - } - if (!sbs_out_put) - return std::nullopt; - - send_msg = ""; - SSR::SBS_MSG msg_base; - if (!aircraft) - return std::nullopt; - msg_base.set(aircraft.get()); - for (int msg_t = 1; msg_t <= 8; ++msg_t) { - send_msg->append(msg_base.to_msg(msg_t) + "\n"); - } - send_msg->append(msg_base.to_ID() + "\n"); - send_msg->append(msg_base.to_AIR() + "\n"); - send_msg->append(msg_base.to_CLK() + "\n"); - send_msg->append(msg_base.to_SEL() + "\n"); - send_msg->append(msg_base.to_STA() + "\n"); - return send_msg; - } - - bool DF_11_17_18 = - df == SSR::Downlink_Format::All_Call_Reply_11 || - df == SSR::Downlink_Format::Extended_Squitter_17 || - df == SSR::Downlink_Format::Extended_Squitter_Non_Transponder_18; - if (mode_s_output_type == Mode_S_Output_Type::DF_11_17_18 && !DF_11_17_18) - return std::nullopt; - if (mode_s_output_type == Mode_S_Output_Type::NO_POS_Mode_S) { - if (aircraft && aircraft->pos().has_value()) { - return std::nullopt; - } - } - - if (output_format == Output_Data_Format::BIN) { - send_msg = SSR::packet_to_escape_format(s_msg->packet); - // send_msg = create_Binary_Format_memory(msg_hex, signal_level, - // &mlat_timestamp); - } else if (output_format == Output_Data_Format::BIN_ID) { - // std::uint32_t id; - // { - // id = Global::instance()->mlat_server.id; - // } - // auto bin_id_packet = mode_s_msg_packet_to_server_packet(id, - // data->packet); send_msg = packet_to_escape_format(bin_id_packet); - } else if (output_format == Output_Data_Format::AVR) { - send_msg = SSR::create_AVR_format(msg_hex); - } else if (output_format == Output_Data_Format::AVR_MLAT) { - send_msg = create_MLAT_AVR_format(msg_hex, &mlat_timestamp); - } else { - std::cerr << "Unknown output format " << VAR_STR_1(output_format) - << std::endl; - return std::nullopt; - } - } - return send_msg; +std::optional convert_to_send_format(Data_Source_Handler* ds, + const std::shared_ptr& feed, + const std::shared_ptr& msg) { + auto& type = msg->type; + auto fs = dynamic_cast(msg->source.get()); + if (fs) { + if (fs->play_mode == Play_Mode::analysis) { + // std::cout << fs->key << " analysis i ==" << i << std::endl; + } + } + // 出口输出的条件 + auto& output_format = feed->output_format.type; + auto& use_mode_ac = feed->output_format.use_mode_ac; + auto& use_status = feed->output_format.use_status; + auto& mode_s_output_type = feed->output_format.mode_s_output_type; + // 计算出是否输出消息 + std::optional send_msg = std::nullopt; + if (type == SSR::Msg::HULC_Status) { + if (!use_status) + return std::nullopt; + auto data = static_cast(msg.get()); + if (output_format == Output_Data_Format::BIN || + output_format == Output_Data_Format::BIN_ID) { + send_msg = SSR::packet_to_escape_format(data->packet); + } + } + else if (type == SSR::Msg::Radarcape_status) { + auto data = static_cast(msg.get()); + if (output_format == Output_Data_Format::BIN || + output_format == Output_Data_Format::BIN_ID) { + send_msg = SSR::packet_to_escape_format(data->packet); + } + } + else if (type == SSR::Msg::AC) { + if (!use_mode_ac) + return std::nullopt; + auto data = static_cast(msg.get()); + std::string& msg_hex = data->msg_hex; + char signal_level = data->signal_level; + SSR::MLAT_timestamp& mlat_timestamp = data->mlat_timestamp; + if (output_format == Output_Data_Format::BIN) { + // send_msg = create_Binary_Format_memory(msg_hex, signal_level, + // &mlat_timestamp); + send_msg = SSR::packet_to_escape_format(msg->packet); + } + else if (output_format == Output_Data_Format::BIN_ID) { + // std::uint32_t id; + // { + // id = Global::instance()->mlat_server.id; + // } + // auto bin_id_packet = mode_s_msg_packet_to_server_packet(id, + // data->packet); send_msg = packet_to_escape_format(bin_id_packet); + } + else if (output_format == Output_Data_Format::AVR) { + send_msg = SSR::create_AVR_format(msg_hex); + } + else if (output_format == Output_Data_Format::AVR_MLAT) { + send_msg = create_MLAT_AVR_format(msg_hex, &mlat_timestamp); + } + } + else if (type == SSR::Msg::S7 || type == SSR::Msg::S14) { + auto s_msg = static_cast(msg.get()); + std::string& icao = s_msg->icao; + SSR::Downlink_Format& df = s_msg->df; + std::string& msg_hex = s_msg->msg_hex; + auto& signal_level = s_msg->signal_level; + SSR::MLAT_timestamp& mlat_timestamp = s_msg->mlat_timestamp; + auto aircraft = ds->get_aircraft(s_msg->icao); + if (output_format == Output_Data_Format::SBS) { + bool sbs_out_put = false; + if (feed->output_format.sbs_only_pos) { + auto s = ds->get_aircraft(s_msg->icao); + if (s) { + auto pos = s->pos(); + if (pos.has_value()) { + if (feed->sbs_flm.test(s_msg->icao)) { + sbs_out_put = true; + } + } + } + } + else { + if (feed->sbs_flm.test(s_msg->icao)) { + sbs_out_put = true; + } + } + if (!sbs_out_put) + return std::nullopt; + send_msg = ""; + SSR::SBS_MSG msg_base; + if (!aircraft) + return std::nullopt; + msg_base.set(aircraft.get()); + for (int msg_t = 1; msg_t <= 8; ++msg_t) { + send_msg->append(msg_base.to_msg(msg_t) + "\n"); + } + send_msg->append(msg_base.to_ID() + "\n"); + send_msg->append(msg_base.to_AIR() + "\n"); + send_msg->append(msg_base.to_CLK() + "\n"); + send_msg->append(msg_base.to_SEL() + "\n"); + send_msg->append(msg_base.to_STA() + "\n"); + return send_msg; + } + bool DF_11_17_18 = + df == SSR::Downlink_Format::All_Call_Reply_11 || + df == SSR::Downlink_Format::Extended_Squitter_17 || + df == SSR::Downlink_Format::Extended_Squitter_Non_Transponder_18; + if (mode_s_output_type == Mode_S_Output_Type::DF_11_17_18 && !DF_11_17_18) + return std::nullopt; + if (mode_s_output_type == Mode_S_Output_Type::NO_POS_Mode_S) { + if (aircraft && aircraft->pos().has_value()) { + return std::nullopt; + } + } + if (output_format == Output_Data_Format::BIN) { + send_msg = SSR::packet_to_escape_format(s_msg->packet); + // send_msg = create_Binary_Format_memory(msg_hex, signal_level, + // &mlat_timestamp); + } + else if (output_format == Output_Data_Format::BIN_ID) { + // std::uint32_t id; + // { + // id = Global::instance()->mlat_server.id; + // } + // auto bin_id_packet = mode_s_msg_packet_to_server_packet(id, + // data->packet); send_msg = packet_to_escape_format(bin_id_packet); + } + else if (output_format == Output_Data_Format::AVR) { + send_msg = SSR::create_AVR_format(msg_hex); + } + else if (output_format == Output_Data_Format::AVR_MLAT) { + send_msg = create_MLAT_AVR_format(msg_hex, &mlat_timestamp); + } + else { + std::cerr << "Unknown output format " << VAR_STR_1(output_format) + << std::endl; + return std::nullopt; + } + } + return send_msg; } -void Data_Source_Handler::push_to_feed(const std::shared_ptr &msg) { - if (need_refresh_data_feed_key_list) { - refresh_data_feed_key_list(); - need_refresh_data_feed_key_list = false; - } - auto &other_size = Global::instance()->mode_acs.mode_other_max_num; - auto &s_size = Global::instance()->mode_acs.mode_other_max_num; - std::vector list; - - for (const auto &item : cached_data_feed_key_list) { - auto &key = item.key; - auto opt_feed = Global::instance()->mode_acs.data_feed_config.map.get(key); - if (!opt_feed.has_value()) { - std::cout << "wrong data feed: " << key << std::endl; - break; - } - std::shared_ptr &feed = opt_feed.value(); - if (!feed->enable) - continue; - - if (msg->type == SSR::Mode_Msg::T::S7 || - msg->type == SSR::Mode_Msg::T::S14) { - // static Frequency_Limit fl; - // if (!fl.test()) { - // std::ostringstream oss; - // oss << "收到消息 ===" << VAR_STR_3(msg->type - // ,feed->msg_buffer.mode_s_msg_num, s_size) << std::endl; std::cout - // << oss.str() << std::endl; - // } - - if (feed->msg_buffer.mode_s_msg_num > s_size) { - continue; - } else { - ++feed->msg_buffer.mode_s_msg_num; - } - } else { - if (feed->msg_buffer.mode_other_msg_num > other_size) { - continue; - } else { - ++feed->msg_buffer.mode_other_msg_num; - } - } - std::optional binary = convert_to_send_format(this, feed, msg); - if (binary.has_value()) { - feed->msg_buffer.push(binary.value()); - } - } +void Data_Source_Handler::push_to_feed(const std::shared_ptr& msg) { + if (need_refresh_data_feed_key_list) { + refresh_data_feed_key_list(); + need_refresh_data_feed_key_list = false; + } + auto& other_size = Global::instance()->mode_acs.mode_other_max_num; + auto& s_size = Global::instance()->mode_acs.mode_other_max_num; + std::vector list; + for (const auto& item : cached_data_feed_key_list) { + auto& key = item.key; + auto opt_feed = Global::instance()->mode_acs.data_feed_config.map.get(key); + if (!opt_feed.has_value()) { + std::cout << "wrong data feed: " << key << std::endl; + break; + } + std::shared_ptr& feed = opt_feed.value(); + if (!feed->enable) + continue; + if (msg->type == SSR::Mode_Msg::T::S7 || + msg->type == SSR::Mode_Msg::T::S14) { + // static Frequency_Limit fl; + // if (!fl.test()) { + // std::ostringstream oss; + // oss << "收到消息 ===" << VAR_STR_3(msg->type + // ,feed->msg_buffer.mode_s_msg_num, s_size) << std::endl; std::cout + // << oss.str() << std::endl; + // } + if (feed->msg_buffer.mode_s_msg_num > s_size) { + continue; + } + else { + ++feed->msg_buffer.mode_s_msg_num; + } + } + else { + if (feed->msg_buffer.mode_other_msg_num > other_size) { + continue; + } + else { + ++feed->msg_buffer.mode_other_msg_num; + } + } + std::optional binary = convert_to_send_format(this, feed, msg); + if (binary.has_value()) { + feed->msg_buffer.push(binary.value()); + } + } } Psc::JSON Data_Source_Handler::get_all_connect_feed_status() { - Psc::JSON ret = Psc::JSON::object(); - std::vector list; - { - std::lock_guard g(cdf_mtx); - list = cached_data_feed_key_list; - } - for (auto &i : list) { - Psc::JSON cur = Psc::JSON::object(); - auto odf = Global::instance()->mode_acs.data_feed_config.map.get(i.key); - if (odf.has_value()) { - const auto &df = odf.value(); - i.mode_s_cache_num.update(df->msg_buffer.mode_s_msg_num); - i.mode_other_cache_num.update(df->msg_buffer.mode_other_msg_num); - cur.append({"mode_s_msg_num", i.mode_s_cache_num.to_json()}); - cur.append({"mode_other_msg_num", i.mode_other_cache_num.to_json()}); - } - ret.append({i.key, cur}); - } - return ret; + Psc::JSON ret = Psc::JSON::object(); + std::vector list; + { + std::lock_guard g(cdf_mtx); + list = cached_data_feed_key_list; + } + for (auto& i : list) { + Psc::JSON cur = Psc::JSON::object(); + auto odf = Global::instance()->mode_acs.data_feed_config.map.get(i.key); + if (odf.has_value()) { + const auto& df = odf.value(); + i.mode_s_cache_num.update(df->msg_buffer.mode_s_msg_num); + i.mode_other_cache_num.update(df->msg_buffer.mode_other_msg_num); + cur.append({"mode_s_msg_num", i.mode_s_cache_num.to_json()}); + cur.append({"mode_other_msg_num", i.mode_other_cache_num.to_json()}); + } + ret.append({i.key, cur}); + } + return ret; } + Psc::JSON Data_Source_Handler::get_all_connect_feed() { - Psc::JSON ret = Psc::JSON::array(); - std::vector list; - { - std::lock_guard g(cdf_mtx); - list = cached_data_feed_key_list; - } - for (auto &i : list) { - Psc::JSON cur = Psc::JSON::object(); - cur.append({"key", i.key}); - ret.append(cur); - } - return ret; -} \ No newline at end of file + Psc::JSON ret = Psc::JSON::array(); + std::vector list; + { + std::lock_guard g(cdf_mtx); + list = cached_data_feed_key_list; + } + for (auto& i : list) { + Psc::JSON cur = Psc::JSON::object(); + cur.append({"key", i.key}); + ret.append(cur); + } + return ret; +} diff --git a/module/Local_Server/Data_Source/Data_Source_Handler.h b/module/Local_Server/Data_Source/Data_Source_Handler.h index 434c849..0942519 100644 --- a/module/Local_Server/Data_Source/Data_Source_Handler.h +++ b/module/Local_Server/Data_Source/Data_Source_Handler.h @@ -1,50 +1,41 @@ #pragma once #include - #include "Core/Base/SM_RingBuffer.h" #include "Core/Serial/Serial_Coro.h" - #include "Core/Statistics/Frequency_Limit.h" #include "Core/Statistics/Statistics.h" #include "Core/transmit_protocol/core/statistics.h" - #include "Database.h" #include "Local_Server/global_include.h" #include "global.h" #include "PlayBack.h" - - // 这个函数专门装cpu密集函数 放到线程池去处理 -class Data_Source_Handler : public DataBase -{ +class Data_Source_Handler : public DataBase { public: - std::shared_ptr create_msg(const std::string& packet); - - virtual void origin_data_transform_mode_data(std::string& origin_data){}; - virtual void before_handle_msg(std::shared_ptr& msg){}; - - virtual void handle_mode_s(std::shared_ptr msg); - void handle_HULC(const std::string& packet); - void process_mode_acs_data(const std::string& mode_data); - Mode_AC_Statistic_Data mode_ac_statistic; - Mode_S_Statistic_Data mode_s_statistic; - Psc::Speed_Statistics read_speed; - Psc::Value_Statistics value_statistics; - ~Data_Source_Handler() override {}; - - // 推送到 data_feed 相关代码 - void push_to_feed(const std::shared_ptr &msg); - void refresh_data_feed_key_list(); - struct Cached_Source_Info { - std::string key; - Psc::Value_Statistics mode_s_cache_num; - Psc::Value_Statistics mode_other_cache_num; - }; - std::atomic need_refresh_data_feed_key_list = true; - std::vector cached_data_feed_key_list{}; - Psc::JSON get_all_connect_feed_status(); - Psc::JSON get_all_connect_feed(); - std::mutex cdf_mtx; + std::shared_ptr create_msg(const std::string& packet); + virtual void origin_data_transform_mode_data(std::string& origin_data) {}; + virtual void before_handle_msg(std::shared_ptr& msg) {}; + virtual void handle_mode_s(std::shared_ptr msg); + void handle_HULC(const std::string& packet); + size_t process_mode_acs_data(const std::string& mode_data); + Mode_AC_Statistic_Data mode_ac_statistic; + Mode_S_Statistic_Data mode_s_statistic; + Psc::Speed_Statistics read_speed; + Psc::Value_Statistics value_statistics; + ~Data_Source_Handler() override = default; + // 推送到 data_feed 相关代码 + void push_to_feed(const std::shared_ptr& msg); + void refresh_data_feed_key_list(); + struct Cached_Source_Info { + std::string key; + Psc::Value_Statistics mode_s_cache_num; + Psc::Value_Statistics mode_other_cache_num; + }; + std::atomic need_refresh_data_feed_key_list = true; + std::vector cached_data_feed_key_list{}; + Psc::JSON get_all_connect_feed_status(); + Psc::JSON get_all_connect_feed(); + std::mutex cdf_mtx; }; diff --git a/module/Local_Server/server/With_Loop_Coro.cpp b/module/Local_Server/server/With_Loop_Coro.cpp index 70f3599..65ad7f7 100644 --- a/module/Local_Server/server/With_Loop_Coro.cpp +++ b/module/Local_Server/server/With_Loop_Coro.cpp @@ -1,32 +1,46 @@ #include "With_Loop_Coro.h" -With_Loop_Coro::~With_Loop_Coro() {} +With_Loop_Coro::~With_Loop_Coro() = default; + void With_Loop_Coro::async_stop() { - enable = false; - loop_task.reset(); + enable = false; } -void With_Loop_Coro::sync_wait() { - if (!loop_task) - return; - while (loop_task->status() != concurrencpp::result_status::idle) {} + +void With_Loop_Coro::sync_wait() const { + if (!loop_task) { + return; + } + auto last = std::chrono::steady_clock::now(); + while (loop_task->status() == concurrencpp::result_status::idle) { + auto now = std::chrono::steady_clock::now(); + if (now - last > std::chrono::seconds(1)) { + std::cout << std::format("等待任务退出 {}:{}\n", type, key); + last = now; + } + std::this_thread::sleep_for(std::chrono::milliseconds(10)); + } } -bool With_Loop_Coro::running() { - if (!loop_task) - return false; - return loop_task->status() == concurrencpp::result_status::idle; + +bool With_Loop_Coro::running() const { + if (!loop_task) { + return false; + } + return loop_task->status() == concurrencpp::result_status::idle; } -concurrencpp::result With_Loop_Coro::sync_coro_loop_and_enable( - std::shared_ptr executor) { - std::string name = type + ":" + key; - if (enable && !running()) { - co_await _open(); - loop_task = std::make_shared>(loop_coro(executor)); - std::cout << std::format("启动任务 {}!\n", name); - } - else if (!enable && running()) { - std::cout << std::format("等待停止任务 {}!\n", name); - sync_wait(); - co_await _close(); - std::cout << std::format("停止任务成功 {}!\n", name); - } - co_return; + +concurrencpp::result With_Loop_Coro::sync_coro_loop_and_enable() { + std::string name = type + ":" + key; + if (loop_task && !running()) { + loop_task.reset(); + co_await _close(); + } + if (enable && !loop_task) { + co_await _open(); + loop_task = std::make_shared>(loop_coro()); + std::cout << std::format("启动任务 {}!\n", name); + } + else if (!enable && running()) { + std::cout << std::format("请求停止任务 {}!\n", name); + force_close(); + } + co_return; } diff --git a/module/Local_Server/server/With_Loop_Coro.h b/module/Local_Server/server/With_Loop_Coro.h index 00b1ad3..f949ea6 100644 --- a/module/Local_Server/server/With_Loop_Coro.h +++ b/module/Local_Server/server/With_Loop_Coro.h @@ -3,37 +3,37 @@ #include #include #include +#include #include #include #include +#include #include #include - #include "Core/Base/JSON.h" - class With_Loop_Coro_Data { public: - std::string key; - Psc::Copyable_Atomic enable{}; - std::string type; - PSC_USE_JSON + std::string key; + Psc::Copyable_Atomic enable{}; + std::string type; + PSC_USE_JSON }; - - class With_Loop_Coro : public With_Loop_Coro_Data { public: - virtual ~With_Loop_Coro(); - std::shared_ptr> loop_task; - virtual concurrencpp::result - loop_coro(std::shared_ptr executor) = 0; - void async_stop(); - void sync_wait(); - bool running(); - // 同步协程循环 和enable的关系 - concurrencpp::result sync_coro_loop_and_enable( - std::shared_ptr executor); + virtual ~With_Loop_Coro(); + std::shared_ptr> loop_task; + virtual concurrencpp::result loop_coro() = 0; + void async_stop(); + void sync_wait() const; + bool running() const; + virtual void force_close() {} + concurrencpp::result sync_coro_loop_and_enable(); - // 这个关闭打开指的是内部的socket serial 等的关闭打开 - virtual concurrencpp::result _open() { co_return; } - virtual concurrencpp::result _close() { co_return; } + virtual concurrencpp::result _open() { + co_return; + } + + virtual concurrencpp::result _close() { + co_return; + } }; diff --git a/module/Local_Server/server/io_coro.h b/module/Local_Server/server/io_coro.h index 8e1c248..b5d0a09 100644 --- a/module/Local_Server/server/io_coro.h +++ b/module/Local_Server/server/io_coro.h @@ -1,17 +1,21 @@ #pragma once - -#include "With_Loop_Coro.h" - -class Coro { +#include +#include +#include +#include +#include +#include "psc_global_include/Singleton.hpp" +class Coro : public Psc::Singleton { public: - void start(); - void stop(); - + void start(); + void stop(); + concurrencpp::result sleep_for(std::chrono::milliseconds ms); + std::shared_ptr process_data; + std::shared_ptr io; private: - concurrencpp::result coro_thread(); - bool has_running_loop_tasks(); - concurrencpp::runtime runtime_; - std::shared_ptr executor_; - std::unique_ptr> data_feed_thread_task; - std::atomic running = false; + concurrencpp::result coro_thread(); + bool has_running_loop_tasks(); + concurrencpp::runtime runtime_; + std::unique_ptr> data_feed_thread_task; + std::atomic running = false; }; diff --git a/module/Local_Server_main.cpp b/module/Local_Server_main.cpp index 80baf68..eecf7ca 100644 --- a/module/Local_Server_main.cpp +++ b/module/Local_Server_main.cpp @@ -15,163 +15,169 @@ #include #endif struct Catch_Memory { - Catch_Memory() { - sm = (std::int64_t)get_system_memory(); - cur = (std::int64_t)get_process_memory(); - } - std::int64_t MB = 1024 * 1024; - bool catch_ok() { - auto old_memory = cur; - cur = (std::int64_t)get_process_memory(); - auto change_mb = (cur - old_memory) / MB; - auto cur_mb = cur / MB; - // std::cout << get_current_date_string() << " 时内存" << cur_mb << "MB " - // << " 变更" << change_mb << "MB" << std::endl; - if (cur > memory_max) { - auto rate = (double)cur / (double)sm; - std::cout << get_current_date_string() + " 抓住内存暴涨:" << cur_mb - << "MB" << " 变更" << change_mb << "MB" << std::endl; - std::cout << "\t内存占用" << rate << "%" << std::endl; - stop_program = SIGINT; + Catch_Memory() { + sm = (std::int64_t)get_system_memory(); + cur = (std::int64_t)get_process_memory(); + } + + std::int64_t MB = 1024 * 1024; + + bool catch_ok() { + auto old_memory = cur; + cur = (std::int64_t)get_process_memory(); + auto change_mb = (cur - old_memory) / MB; + auto cur_mb = cur / MB; + // std::cout << get_current_date_string() << " 时内存" << cur_mb << "MB " + // << " 变更" << change_mb << "MB" << std::endl; + if (cur > memory_max) { + auto rate = (double)cur / (double)sm; + std::cout << get_current_date_string() + " 抓住内存暴涨:" << cur_mb + << "MB" << " 变更" << change_mb << "MB" << std::endl; + std::cout << "\t内存占用" << rate << "%" << std::endl; + stop_program = SIGINT; #if WIN32 #else - system("top"); + system("top"); #endif - return true; - } - return false; - } + return true; + } + return false; + } #if WIN32 - std::int64_t memory_max = 1 * 1024 * 1024 * 1024; + std::int64_t memory_max = 1 * 1024 * 1024 * 1024; #else - std::int64_t memory_max = 1 * 1024 * 1024 * 1024; + std::int64_t memory_max = 1 * 1024 * 1024 * 1024; #endif - std::int64_t cur; - std::int64_t sm; + std::int64_t cur; + std::int64_t sm; }; + int psc_main(int argc, char* argv[]) { - std::cout << "wyc_main" << std::endl; - if (argc >= 2) { - std::string config_path = argv[1]; - if (config_path.at(0) == '@') { - config_path.replace(0, 1, get_exe_dir()); - } - ::default_config_path = config_path; - } - // std::cout << get_stack_trace() << std::endl; - init_signal_config({SIGINT, SIGTERM}, + std::cout << "wyc_main" << std::endl; + if (argc >= 2) { + std::string config_path = argv[1]; + if (config_path.at(0) == '@') { + config_path.replace(0, 1, get_exe_dir()); + } + ::default_config_path = config_path; + } + // std::cout << get_stack_trace() << std::endl; + init_signal_config({SIGINT, SIGTERM}, #ifdef WIN32 - {} + {} #else - { SIGPIPE } + { + SIGPIPE + } #endif - ); - auto clear = []() { - std::cout << "保存配置文件 " << LOG_POS << std::endl; - Config::save(); - std::cout << "shutdown" << std::endl; - auto i = Global::instance(); - i->svr.stop(); - i->thread_manager.stop_all_thread(); - Global::instance()->dsp_config.close_dsp_device(); - std::cout << "destroy开始" << std::endl; - Global::destroy(); - std::cout << " Base_Logger_Manager::instance()->destroy()开始" << std::endl; - Base_Logger_Manager::destroy(); - std::cout << " clear完成" << std::endl; - std::cout << " 正常退出" << std::endl; - }; - auto g = Global::instance(); - Psc::set_fail_fast([](const std::string& name) { - // 如果是在 Global::instance() 里面失败是不能调用这个处理函数的 - auto g = Global::instance(); - std::cout << "set_fail_fast 退出原因: 222" << name << std::endl; - std::cout << "shutdown" << LOG_POS << std::endl; - auto id = std::this_thread::get_id(); - std::cout << "id: " << id << std::endl; - Detach_Thread* dt = g->thread_manager.get_thread(id); - if (!dt) { - std::cout << VAR_STR_1((void*)dt) << std::endl; - std::terminate(); - } - std::set excluded_thread; - excluded_thread.insert(dt->name); - std::cout << dt->name << std::endl; - // std::cout << "保存配置文件 " << LOG_POS << std::endl; - // Config::save(); - g->svr.stop(); - g->thread_manager.stop_all_thread(10000, excluded_thread); - std::cout << "22222222" << std::endl; - Global::instance()->dsp_config.close_dsp_device(); - std::cout << "destroy开始" << std::endl; - Global::destroy(); - std::cout << " Base_Logger_Manager::instance()->destroy()开始" << std::endl; - Base_Logger_Manager::destroy(); - std::cout << " clear完成" << std::endl; - std::cout << " std::exit(75) " << name << std::endl; - std::exit(75); - std::cout << "std::exit(75) 完成:" << name << std::endl; - }); - Detach_Thread_Manager& manager = g->thread_manager; - std::cout << "[主线程:" << std::this_thread::get_id() << "]" << " \n" - << std::flush; - manager.test_and_start_thread( - "web服务器线程", [g](std::atomic& running) { - auto& c = Global::instance()->device_config; - std::string ip = "0.0.0.0"; + ); + auto clear = []() { + std::cout << "保存配置文件 " << LOG_POS << std::endl; + Config::save(); + std::cout << "shutdown" << std::endl; + auto i = Global::instance(); + i->svr.stop(); + i->thread_manager.stop_all_thread(); + Global::instance()->dsp_config.close_dsp_device(); + std::cout << "destroy开始" << std::endl; + Global::destroy(); + std::cout << " Base_Logger_Manager::instance()->destroy()开始" << std::endl; + Base_Logger_Manager::destroy(); + std::cout << " clear完成" << std::endl; + std::cout << " 正常退出" << std::endl; + }; + auto g = Global::instance(); + Psc::set_fail_fast([](const std::string& name) { + // 如果是在 Global::instance() 里面失败是不能调用这个处理函数的 + auto g = Global::instance(); + std::cout << "set_fail_fast 退出原因: 222" << name << std::endl; + std::cout << "shutdown" << LOG_POS << std::endl; + auto id = std::this_thread::get_id(); + std::cout << "id: " << id << std::endl; + Detach_Thread* dt = g->thread_manager.get_thread(id); + if (!dt) { + std::cout << VAR_STR_1((void*)dt) << std::endl; + std::terminate(); + } + std::set excluded_thread; + excluded_thread.insert(dt->name); + std::cout << dt->name << std::endl; + // std::cout << "保存配置文件 " << LOG_POS << std::endl; + // Config::save(); + g->svr.stop(); + g->thread_manager.stop_all_thread(10000, excluded_thread); + std::cout << "22222222" << std::endl; + Global::instance()->dsp_config.close_dsp_device(); + std::cout << "destroy开始" << std::endl; + Global::destroy(); + std::cout << " Base_Logger_Manager::instance()->destroy()开始" << std::endl; + Base_Logger_Manager::destroy(); + std::cout << " clear完成" << std::endl; + std::cout << " std::exit(75) " << name << std::endl; + std::exit(75); + std::cout << "std::exit(75) 完成:" << name << std::endl; + }); + Detach_Thread_Manager& manager = g->thread_manager; + std::cout << "[主线程:" << std::this_thread::get_id() << "]" << " \n" + << std::flush; + manager.test_and_start_thread( + "web服务器线程", [g](std::atomic& running) { + auto& c = Global::instance()->device_config; + std::string ip = "0.0.0.0"; #ifdef WIN32 - ip = "127.0.0.1"; + ip = "127.0.0.1"; #endif - Net_Config* device = c.list.get("device").value(); - std::cout << "http://" + ip + ":" + std::to_string(device->port) + "\n" - << std::flush; - std::cout << "http://" + device->ip + ":" + - std::to_string(device->port) + "\n" - << std::flush; - if (!g->svr.listen("0.0.0.0", device->port)) { - if (running.load(std::memory_order_acquire)) { - std::cout << "http://" + ip + ":" + std::to_string(device->port) + - "启动失败 退出!\n" - << std::flush; - std::cout << "http://" + device->ip + ":" + - std::to_string(device->port) + "启动失败 退出!\n" - << std::flush; - std::exit(0); - } - } - }); - // manager.test_and_start_thread("io_coro 协程线程", io_coro); - static int t = Global::instance()->mode_acs.read_milliseconds; - g->dsp_config.init_env(); - bool enable = g->mlat.enable; - Coro coro; - coro.start(); - // Catch_Memory cm; - while (stop_program == 0) { - for (auto& ds : g->mode_acs.data_source_config.map.list()) { - ds->delete_timeout_aircraft(); - } - if (enable) { - g->mlat.refresh(); - } + Net_Config* device = c.list.get("device").value(); + std::cout << "http://" + ip + ":" + std::to_string(device->port) + "\n" + << std::flush; + std::cout << "http://" + device->ip + ":" + + std::to_string(device->port) + "\n" + << std::flush; + if (!g->svr.listen("0.0.0.0", device->port)) { + if (running.load(std::memory_order_acquire)) { + std::cout << "http://" + ip + ":" + std::to_string(device->port) + + "启动失败 退出!\n" + << std::flush; + std::cout << "http://" + device->ip + ":" + + std::to_string(device->port) + "启动失败 退出!\n" + << std::flush; + std::exit(0); + } + } + }); + // manager.test_and_start_thread("io_coro 协程线程", io_coro); + static int t = Global::instance()->mode_acs.read_milliseconds; + g->dsp_config.init_env(); + bool enable = g->mlat.enable; + auto coro = Coro::instance(); + coro->start(); + // Catch_Memory cm; + while (stop_program == 0) { + for (auto& ds : g->mode_acs.data_source_config.map.list()) { + ds->delete_timeout_aircraft(); + } + if (enable) { + g->mlat.refresh(); + } #ifdef __linux__ - if (g->mode_acs.monitor_msg_live) - malloc_trim(0); + if (g->mode_acs.monitor_msg_live) + malloc_trim(0); #endif - std::this_thread::sleep_for(std::chrono::seconds(3)); - if (Global::instance()->init_ok) { - // if (cm.catch_ok()) { - // stop_program = SIGINT; - // break; - // } - } - } - coro.stop(); - if (stop_program == SIGINT || stop_program == SIGTERM) { - clear(); - } - return 0; + std::this_thread::sleep_for(std::chrono::seconds(3)); + if (Global::instance()->init_ok) { + // if (cm.catch_ok()) { + // stop_program = SIGINT; + // break; + // } + } + } + coro->stop(); + if (stop_program == SIGINT || stop_program == SIGTERM) { + clear(); + } + return 0; } + int main(int argc, char* argv[]) { - return redict_main_with_gtest(argc, argv, psc_main); -} \ No newline at end of file + return redict_main_with_gtest(argc, argv, psc_main); +}