From b05d9fe6c6a31082353b1f73ffa0af21f65f24e6 Mon Sep 17 00:00:00 2001 From: wyc <1104749580@qq.com> Date: Fri, 17 Jul 2026 13:52:10 +0800 Subject: [PATCH] =?UTF-8?q?=E9=A6=96=E4=B8=AA=E7=82=B9=E5=BC=82=E5=B8=B8?= =?UTF-8?q?=E4=BD=8D=E7=BD=AE=E5=89=94=E9=99=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FAQ.md | 28 +++++++++++++++++++ .../Data_Source/Data_Source_Handler.cpp | 1 + 2 files changed, 29 insertions(+) create mode 100644 FAQ.md diff --git a/FAQ.md b/FAQ.md new file mode 100644 index 0000000..971c235 --- /dev/null +++ b/FAQ.md @@ -0,0 +1,28 @@ +1.项目是什么,解决什么问题? +该项目类似 Radarcape,是一个基于 ADS-B/Mode-S 信号的飞机态势实时数据处理平台。同时支持多种数据源接入,并将解析后的航空态势数据通过多种方式进行转发。 +同时支持多种数据源,数据转发。 +2.整体架构(前端、后端、数据库、通信? +整体采用前后端分离架构。前端 React + Ant Design + Leaflet 负责地图态势展示。后端基于 C++20 开发,采用 Drogon 提供 Web 服务能力, +结合 Asio coroutine 实现异步 IO,多数据源通过统一适配层接入。 +3.遇到的最大技术挑战? +3.1 高并发 IO难点 1:高并发 IO +为了避免一个数据源数据馈送点开一个线程,和减少多个线程的锁争用带来的问题。因此采用 Asio 协程模型, IO 操作通过 coroutine +异步调度, +避免大量连接创建线程;CPU 密集型解析任务通过线程池执行,实现 IO 和计算分离,避免cpu耗时操作阻塞流程。 +3.2 Mode-S解析 +Mode-S 报文格式复杂,需要根据英文协议文档实现不同类型报文解析,并处理 CRC 校验以及奇偶校验定位。 +3.3 实时地图刷新 +飞机位置更新频率高,如果每次数据变化都刷新 React 全组件,会导致性能下降,因此优化状态更新粒度。比如轨迹 网页会缓存状态增量获取新的轨迹点 +3.4 +底层数据经常出问题,需要良好的可观测结构,来排除底层数据的各种问题。我在网页上每一种报文都带有自己的状态,每一个飞机所有状态都能看到, +各个数据源内部自己协程的状态机当前状态,历史状态切换,当前数据的单包大小平均值 数据速度。以及解析位置的CPR状态,每一个轨迹点的解析速度判断流程 +都可以观测,tcp服务端连接了几个客户端都可以看到 +4.你的职责? +我负责前端和后端 + +TCP、UDP、串口、文件、DLL 这些输入方式差异很大,你是怎么设计统一接口的? +我的设计思路是将数据接入层和数据解析层解耦。解析模块只关心统一的数据流,不关心数据来自 TCP、UDP、串口还是文件。 +我设计了一个抽象的数据源接口,例如定义初始化、启动、停止、读取数据等基础生命周期接口。 +不同数据源分别实现这个接口 +数据源最终是把二进制流封装成消息对象,传递给消息处理线程池,处理完成后,根据与数据转发的连接关系,传递给数据转发。 + diff --git a/module/Local_Server/Data_Source/Data_Source_Handler.cpp b/module/Local_Server/Data_Source/Data_Source_Handler.cpp index 7cfad9d..a38c552 100644 --- a/module/Local_Server/Data_Source/Data_Source_Handler.cpp +++ b/module/Local_Server/Data_Source/Data_Source_Handler.cpp @@ -183,6 +183,7 @@ void Data_Source_Handler::handle_mode_s(std::shared_ptr mode_s_ bool time_space_filter = cfg.time_space_filter.load(); bool speed_filter = cfg.speed_filter.load(); bool use_system_time = source->ignore_msg_time.load(); + SSR::ADS_B_T::Constraint air_constraint{cfg.max_speed_m_s, cfg.air_pos_timeout, SSR::cpr_cb, time_space_filter, speed_filter, use_system_time}; SSR::ADS_B_T::Constraint surface_constraint{cfg.max_speed_m_s, cfg.surface_pos_timeout, SSR::cpr_cb, time_space_filter, speed_filter, use_system_time}; SSR::parse_mode_s_bin(source.get(), mode_s_msg,