02 — 云融(YunRong)· 系统架构设计文档
前置文档:01-需求分析文档
版本:v0.1
状态:已发布
最后更新:2025-01
1. 架构概述
1.1 设计目标
| 目标 | 说明 |
|---|
| 分层解耦 | 上层不依赖下层实现细节,面向接口编程,层间通过明确的数据结构传递 |
| 网络优先 | 网络层作为一等公民独立成层,具备完整的连接管理、协议编解码、可靠性保障能力 |
| GUI 不阻塞 | 任何可能阻塞的操作(网络 IO、文件读写、数据库查询)均在非 GUI 线程执行 |
| 可测试性 | 核心业务逻辑不依赖 Qt GUI 类,可脱离界面运行单元测试 |
| 跨平台 | 平台差异代码隔离在 Platform Abstraction Layer,核心代码 100% 跨平台 |
1.2 四层架构
┌────────────────────────────────────────────────────────────┐
│ Presentation Layer (GUI) │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────────┐ │
│ │ 主窗口 │ │ 聊天视图 │ │ 联系人树 │ │ 数据统计面板 │ │
│ │ MainWin │ │ ChatView │ │ OrgTree │ │ Dashboard │ │
│ └────┬─────┘ └────┬─────┘ └────┬─────┘ └──────┬───────┘ │
│ └─────────────┴────────────┴───────────────┘ │
│ │ Qt Signal/Slot │
├──────────────────────────┼──────────────────────────────────┤
│ Application Layer (业务逻辑) │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────────┐ │
│ │ IMService│ │TaskService│ │FileService│ │ReportService │ │
│ └────┬─────┘ └────┬─────┘ └────┬─────┘ └──────┬───────┘ │
│ └─────────────┴────────────┴───────────────┘ │
│ │ C++ 接口 │
├──────────────────────────┼──────────────────────────────────┤
│ Service Layer (服务层) │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────────┐ │
│ │NetworkMgr│ │ DataMgr │ │ConfigMgr │ │ LogService │ │
│ │ WS+HTTP │ │SQLite + │ │ │ │ │ │
│ │ │ │Remote HTTP│ │ │ │ │ │
│ └────┬─────┘ └────┬─────┘ └──────────┘ └──────────────┘ │
│ │ │ │
├───────┼────────────┼────────────────────────────────────────┤
│ │ Infrastructure Layer (基础设施) │
│ ┌────┴────────────┴──────┐ ┌──────────┐ ┌──────────────┐ │
│ │ ThreadPool / Queue │ │ Crypto │ │ Serialization │ │
│ │ (多线程 + 无锁队列) │ │ (TLS) │ │ (JSON/Binary) │ │
│ └────────────────────────┘ └──────────┘ └──────────────┘ │
└─────────────────────────────────────────────────────────────┘
2. 模块分解
2.1 模块总览
client/src/
├── core/ # 核心库(无 Qt GUI 依赖)
│ ├── net/ # 网络通信层 ⭐核心强化模块
│ │ ├── connection_mgr.cpp # 连接管理器(连接池 + 生命周期)
│ │ ├── ws_client.cpp # WebSocket 客户端
│ │ ├── http_client.cpp # HTTP 客户端
│ │ ├── heartbeat.cpp # 心跳保活
│ │ ├── reconnect_strategy.cpp # 断线重连策略
│ │ ├── protocol.cpp # 协议编解码(JSON 帧 + 二进制帧)
│ │ └── rate_limiter.cpp # 流控 / 限速
│ ├── data/ # 数据访问层
│ │ ├── i_data_store.h # 存储抽象接口 (Strategy 模式)
│ │ ├── sqlite_store.cpp # SQLite 实现
│ │ ├── sync_mgr.cpp # 同步管理器
│ │ └── cache_mgr.cpp # 本地缓存管理
│ ├── model/ # 数据模型(纯数据结构,跨层共享)
│ │ ├── message.cpp # 消息
│ │ ├── conversation.cpp # 会话
│ │ ├── contact.cpp # 联系人
│ │ ├── task.cpp # 任务
│ │ └── file_transfer.cpp # 传输任务
│ ├── service/ # 业务服务
│ │ ├── im_service.cpp # IM 业务逻辑
│ │ ├── task_service.cpp # 任务业务逻辑
│ │ ├── file_service.cpp # 文件传输业务逻辑
│ │ └── report_service.cpp # 报表业务逻辑
│ └── infra/ # 基础设施
│ ├── thread_pool.cpp # 线程池
│ ├── msg_bus.cpp # 线程间消息总线(无锁队列)
│ ├── config_mgr.cpp # 配置管理 (Singleton)
│ ├── logger.cpp # 日志服务
│ └── crypto.cpp # 加密工具
│
├── gui/ # GUI 层(依赖 Qt Widgets)
│ ├── main_window.cpp # 主窗口(导航 + 内容区 + 信息面板)
│ ├── views/
│ │ ├── chat_view.cpp # 聊天视图(消息气泡列表 + 输入框)
│ │ ├── contact_tree.cpp # 组织架构树
│ │ ├── task_list.cpp # 任务列表
│ │ ├── file_panel.cpp # 文件传输面板
│ │ └── dashboard.cpp # 数据统计面板
│ ├── widgets/ # 自定义控件
│ │ ├── message_bubble.cpp # 消息气泡 Delegate
│ │ ├── avatar_widget.cpp # 头像控件
│ │ ├── speed_chart.cpp # 实时传输速度曲线
│ │ ├── toast_notify.cpp # Toast 通知弹窗
│ │ └── status_indicator.cpp # 在线状态指示灯
│ ├── models/ # Qt Model 适配层
│ │ ├── conversation_model.cpp
│ │ ├── message_list_model.cpp
│ │ └── contact_tree_model.cpp
│ └── delegates/ # 自定义渲染
│ └── message_delegate.cpp
│
├── app/
│ └── main.cpp # 应用入口
│
├── tests/ # 测试
│ ├── unit/ # 单元测试
│ └── integration/ # 集成测试
2.2 模块职责矩阵
| 模块 | 职责 | 依赖 |
|---|
net/connection_mgr | 管理所有 TCP/WS/HTTP 连接的生命周期,提供连接池 | infra/thread_pool |
net/ws_client | WebSocket 连接、帧收发、Ping/Pong | net/protocol, Qt WebSocket |
net/http_client | HTTP 请求/响应、多线程下载 | Qt Network, net/protocol |
net/protocol | JSON 帧编解码、二进制帧编解码、序列号管理 | nlohmann/json |
net/heartbeat | 定时 Ping,超时检测,触发重连 | net/ws_client |
net/reconnect_strategy | 指数退避重连算法、状态机 | net/connection_mgr |
data/sqlite_store | 本地数据 CRUD、全文搜索 | SQLite3 C API |
| — | 远程数据通过 Go 后端 REST API 访问,客户端不直连 PostgreSQL | — |
data/sync_mgr | 增量同步引擎,冲突检测 | data/*_store |
service/im_service | 消息路由、会话管理、未读计数 | net/*, data/* |
service/file_service | 上传/下载编排、断点续传逻辑 | net/http_client |
gui/chat_view | 消息气泡渲染、输入处理、滚动优化 | service/im_service |
gui/widgets/* | 通用可复用控件 | Qt Widgets |
3. 设计模式应用总览
设计模式是架构的”关节”——决定模块间如何协作。以下标注了每个模式的具体落点。
| # | 设计模式 | 落点模块 | 动机 |
|---|
| 1 | Observer | 全层:Service → GUI 通过 Signal/Slot | 解耦数据生产与消费,实时推送 |
| 2 | Strategy | data/i_data_store — SQLite vs PG;报表导出 CSV/PDF/JSON | 运行时/编译时切换实现 |
| 3 | Singleton | infra/config_mgr, infra/logger | 全局唯一实例,Meyer’s Singleton(connection_mgr 非 Singleton——将来可能多服务端连接) |
| 4 | Command | net/ — 网络请求对象化(SendMsgCmd, UploadCmd)支持队列/重试/撤销 | 网络请求参数化 + 重试队列 |
| 5 | Factory Method | net/connection_mgr — 根据协议类型创建 WS/HTTP 连接 | URL scheme → 对应 Client |
| 6 | State | net/reconnect — IDLE → CONNECTING → CONNECTED → RECONNECTING → ERROR | 避免 if-else 地狱,状态转移显式化 |
| 7 | Producer-Consumer | infra/msg_bus — Main Thread ↔ Worker Pool ↔ DB Thread 之间通过线程安全队列传递消息 | 无锁队列削峰,保证 GUI 不卡 |
| 8 | Decorator | service/ — 消息处理管线:解密→校验→去重→存储→通知 | 可组合的数据处理链 |
| 9 | Facade | net/connection_mgr — 对外隐藏 WS/HTTP/文件传输的复杂性 | 统一入口,降低上层使用复杂度 |
| 10 | Adapter | gui/ + infra/ — 系统托盘、通知、凭据存储中通过 #ifdef PLATFORM_* 条件编译隔离平台差异 | 隔离 OS 差异 |
4. 线程模型设计
4.1 线程拓扑
┌─────────────────────────────────────────────────────────┐
│ Thread Architecture │
│ │
│ ┌──────────────────────────────────────────────────┐ │
│ │ Main Thread (Qt Event Loop) │ │
│ │ • GUI 渲染/事件 + Signal/Slot 调度 │ │
│ │ • QWebSocket / QNetworkAccessManager (异步 IO) │ │
│ │ • QTimer 心跳 / Token 刷新 / 统计聚合 │ │
│ │ • 轻量级消息路由(接收后直接分发,不做重计算) │ │
│ └────────┬─────────────────────────────────────────┘ │
│ │ QueuedConnection (跨线程 Signal) │
│ ┌────────┴────────────────────────────────────┐ │
│ │ Message Bus (线程安全队列) │ │
│ └────────┬────────────────────────────────────┘ │
│ │ │
│ ┌────────┴──────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ Worker Pool │ │ DB Thread │ │ File Pool │ │
│ │ (N workers) │ │ (SQLite 串行) │ │ (N workers) │ │
│ │ │ │ │ │ │ │
│ │ • Protocol │ │ • 消息 CRUD │ │ • 分块上传 │ │
│ │ 编解码 │ │ • 离线缓存 │ │ • 分块下载 │ │
│ │ • 加密/解密 │ │ • 搜索查询 │ │ • Hash 校验 │ │
│ │ • 消息校验 │ │ │ │ │ │
│ └───────────────┘ └──────────────┘ └───────────────┘ │
└─────────────────────────────────────────────────────────┘
4.2 线程间通信机制
Main Thread Worker Pool DB Thread File Pool
(GUI + Async IO) | | |
│ | | |
│── RawMessage ─►[Signal]│ | |
│ │ 1. 解码/校验/解密 | |
│◄── DecodedMsg ─[Signal]│ | |
│ │ | |
│── StoreMsg ──[Signal]──┼──────────────────────►│ |
│ │ | |
│◄── QueryResult ───────┼──────────[Signal]─────│ |
│ │ | |
│── UploadTask ─[Signal]─┼──────────────────────┼──────────────────►│
│ │ | |
│◄── Progress ──────────┼──────────────────────┼──────[Signal]─────│
| 通道 | 机制 | 方向 | 数据 |
|---|
| Main → WorkerPool | Qt Signal (QueuedConnection) | 单向 | 原始网络字节(RawMessage) |
| WorkerPool → Main | Qt Signal (QueuedConnection) | 单向 | 解码/校验后的消息(DecodedMsg) |
| Main → DB | Qt Signal (QueuedConnection) | 单向 | 待持久化的消息、查询请求 |
| DB → Main | Qt Signal (QueuedConnection) | 单向 | 查询结果、同步完成通知 |
| Main → FilePool | Qt Signal (QueuedConnection) | 单向 | 上传/下载任务 |
| FilePool → Main | Qt Signal (QueuedConnection) | 单向 | 进度更新、完成通知 |
4.3 关键线程安全规则
| 规则 | 说明 |
|---|
| SQLite 单线程写入 | SQLite 的 WAL 模式支持多读单写,但为了简化,所有 SQLite 写操作串行化到一个 DB Thread |
| 异步 IO 在主线程 + 批量/重计算在 Worker Pool | QWebSocket / QNetworkAccessManager 的异步 IO 回调在主线程触发。单条消息的编解码在主线程直通(JSON 解析 2-5μs,避免跨线程调度开销更大)。Worker Pool 仅用于:① 离线同步时的批量消息解码 ② AES 加解密 ③ 文件 SHA-256。解码完成后回传主线程进行 GUI 更新和持久化分发 |
| 文件传输用线程池 | 大文件分块上传/下载可并行,每块在池中独立执行,完成后汇总 |
共享状态用 shared_mutex | 配置对象、联系人缓存等读多写少的数据,用 std::shared_mutex 保护 |
| GUI 线程零等待 | GUI 线程绝不调用 wait()、join()、mutex.lock()(可能阻塞的)——只发信号和读无锁队列 |
5. 网络层架构(核心强化)
5.1 网络分层
┌─────────────────────────────────────────┐
│ application layer 调用 │
│ sendMessage() / uploadFile() / ... │
├─────────────────────────────────────────┤
│ ConnectionManager │
│ • 连接池管理 │
│ • 请求路由 (WS vs HTTP vs File) │
│ • 命令队列 + 重试 │
├──────────────┬──────────────────────────┤
│ WsClient │ HttpClient │
│ • 长连接 │ • 短连接池 │
│ • 帧收发 │ • REST 请求 │
│ • Ping/Pong│ • 分块传输 │
├──────────────┴──────────────────────────┤
│ Protocol Layer │
│ • JSON 帧编解码 │
│ • 二进制帧编解码 │
│ • 序列号 / ACK 管理 │
├─────────────────────────────────────────┤
│ Transport Layer │
│ • Qt Network (TCP / QWebSocket) │
│ • QSslSocket (TLS) │
│ • Socket 选项 (TCP_NODELAY, KEEPALIVE) │
└─────────────────────────────────────────┘
5.2 连接状态机
┌──────────┐
startup ──► │ IDLE │
└────┬─────┘
│ connect()
┌────▼─────┐
┌────►│CONNECTING├────┐
│ └────┬─────┘ │ TLS handshake timeout
│ │ success │ (10s)
│ ┌────▼─────┐ │
│ │CONNECTED │◄───┘
│ └────┬─────┘
│ │ heartbeat fail (3次)
│ │ 或 网络断开
│ ┌────▼──────┐
│ │RECONNECT │
│ │ING │
│ └────┬──────┘
│ │ 指数退避: 1s→2s→4s→8s→16s→30s→60s
└──────────┘
│ 超过最大重试次数 (10次)
┌────▼─────┐
│ ERROR │──► 通知用户手动重连
└──────────┘
5.3 协议帧设计
JSON 控制帧(WebSocket Text 帧)
{
"ver": 1,
"type": "msg|ack|notify|heartbeat|sync|error",
"seq": 12345,
"ts": 1704067200000,
"payload": {}
}
| 字段 | 类型 | 说明 |
|---|
ver | int | 协议版本号,当前为 1 |
type | string | 帧类型,决定 payload 结构 |
seq | uint32 | 单调递增序列号,用于 ACK 对应和去重 |
ts | int64 | Unix 毫秒时间戳 |
payload | object | 根据 type 变化的具体数据 |
二进制帧(文件传输 / 缩略图)
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Total Length (32-bit) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Type (8bit) | Payload Data ... |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 字段 | 大小 | 说明 |
|---|
| Total Length | 4 Bytes | 帧总长度(不含自身),大端序 |
| Type | 1 Byte | 0x01 缩略图, 0x02 文件块, 0x03 ACK |
| Payload | 变长 | 数据载荷 |
5.4 ACK 与重传机制
Client (发送方) Server (接收方)
│ │
│── msg(seq=100, type="msg") ─────►│
│ │── 存储消息
│◄── ack(seq=100) ────────────────│
│ │
│ [标记已送达] │
│ │
│── msg(seq=101) ───────── X 丢失 │
│ │
│ [5s 超时, 重发 seq=101] │
│── msg(seq=101, retry=1) ────────►│
│◄── ack(seq=101) ────────────────│
- 发送方维护
map<seq, SentRecord>,包含发送时间、重试次数、回调
- 定时器每 1s 扫描一次,重发超时未 ACK 的消息(最多 3 次)
- 接收方维护
last_recv_seq,收到的 seq <= last_recv_seq 视为重复,直接回复 ACK 但丢弃
6. 数据流设计
6.1 消息发送全流程
Main Thread Worker Pool Server DB Thread
│ │ │ │
│ sendMessage(msg) │ │ │
│───────────────────►│ │ │
│ │ 1. Protocol 编码 │ │
│ │ 分配 seq │ │
│ │ 序列化 JSON │ │
│◄── EncodedFrame ───│ │ │
│ │ │ │
│ 2. 写入发送缓冲 │ │ │
│ │ │ │
│──────────────────────── WS Send ───────►│ │
│ │ │ │
│◄─────────────────────── WS ACK ────────│ │
│ │ │ │
│ 3. 标记已送达 │ │ │
│ 4. 更新气泡: 已送达 │ │ │
│ │ │ │
│── StoreMsg ────────────────────────────────────►[Signal]──│
│ │ │ 持久化 │
6.2 消息接收全流程
Server Main Thread Worker Pool DB Thread
│ │ │ │
│── WS msg ───►│ │ │
│ │ 收到原始字节 │ │
│ │ │ │
│ │── RawBytes ───────►│ │
│ │ │ 1. Protocol 解码 │
│ │ │ 2. 校验 seq │
│ │ │ 3. 去重检查 │
│ │ │ 4. 解密 (如需要) │
│ │◄── DecodedMsg ─────│ │
│ │ │ │
│ │ 5. 发送 ACK │ │
│───────────────│── WS ACK ─────────►│ │
│ │ │ │
│ │── StoreMsg ────────────────────►[Signal]│
│ │ │ 6. 写入 SQLite│
│ │ │ 7. 更新会话摘要│
│ │ │ │
│ │◄── NewMsg ────────────────[Signal]─────│
│ │ │ │
│ │ 8. 更新聊天列表 │ │
│ │ 9. 当前会话: 追加气泡 │ │
│ │10. 后台: 托盘+Toast │ │
6.3 文件上传流程
Main Thread File Pool Server
│ │ │
│ uploadFile(path) │ │
│───────────────────►│ │
│ │ 1. SHA-256 文件 │
│ │ │
│ │── CheckHash ──────►│
│ │◄── 已存在? ───────│ (秒传判断)
│ │ │
│ │ [不存在, 分块上传] │
│ │ │
│ │── Chunk 0 ────────►│
│◄── progress(5%) ──│ │
│ │── Chunk 1 ────────►│
│◄── progress(10%)──│ │
│ │ ... │
│ │── Chunk N ────────►│
│◄── progress(100%)─│ │
│ │◄── Upload OK ─────│
│◄── uploadDone(url)─│ │
7. 数据库设计概要
详细设计见 04-数据库设计文档.md,此处仅给架构层面的关系。
7.1 数据实体关系
┌──────────┐ ┌──────────────┐ ┌──────────┐
│ Contact │ │ Conversation │ │ Message │
│ (联系人) │◄─────│ (会话) │─────►│ (消息) │
└──────────┘ N:M └──────────────┘ 1:N └──────────┘
│
│ 1:N
┌────┴────┐
│ Task │
│ (任务) │
└─────────┘
┌──────────────┐
│ FileTransfer │ (独立实体,记录所有传输任务)
└──────────────┘
┌──────────┐
│ Config │ (键值对,用户偏好)
└──────────┘
7.2 存储分层策略
| 层 | 存储 | 数据特征 |
|---|
| 热数据 | 内存 (unordered_map) | 最近 50 个会话的摘要、在线联系人状态 |
| 温数据 | SQLite | 近 30 天消息、全部会话元数据、传输历史 |
| 冷数据 | PostgreSQL (服务端) | 全量归档消息、用户账户、组织架构 |
| 本地不存储 | 仅服务端 | 其他用户的敏感信息、系统配置 |
8. 技术选型理由
| 技术 | 选择理由 |
|---|
| C++17 | std::optional, std::variant, std::filesystem, if constexpr |
| Qt 6.9 Widgets | 桌面 GUI + 网络(QWebSocket + QNetworkAccessManager),零外部依赖 |
| Go 1.22+ | 后端服务:gorilla/websocket + Gin REST API + PostgreSQL 驱动 |
| CMake 3.20+ | C++ 客户端构建 |
| SQLite 3 | 客户端本地存储(WAL 模式 + FTS5) |
| PostgreSQL 14+ | Go 后端远程存储(客户端不直连 PG) |
| nlohmann/json | 单头文件 JSON 库,STL-like API,用于协议编解码 |
| spdlog | 高性能异步日志库,支持多 sink(文件 + 控制台 + 旋转) |
9. 关键架构决策记录 (ADR)
ADR-001:客户端网络层使用 Qt 原生 API,后端用 Go
- 背景:项目最初选择 Boost.Asio + Beast 做 WebSocket 客户端,后因依赖沉重(125MB 源码包、30s+ 增量编译、API 兼容性问题)而废弃
- 决策:客户端网络层全部使用 Qt 原生 API(QWebSocket + QNetworkAccessManager),后端服务用 Go
- 理由:
- QWebSocket 与 Qt 信号槽无缝集成,网络回调直接在同一事件循环中处理
- 心跳用 QTimer,重连用 QTimer 延迟回调,无需 asio::steady_timer
- 零外部依赖——Qt 6 自带完整的网络模块
- Go 后端自然支持高并发 WebSocket + REST,部署简单(单二进制)
- 代价:QWebSocket 不支持二进制帧的自定义 socket 选项,但对本项目无影响
ADR-002:SQLite 访问串行化到单独线程
- 背景:SQLite 支持多线程(WAL 模式),可多读单写
- 决策:所有 SQLite 访问(读写均)通过 DB Thread 的消息队列串行化
- 理由:
- 避免”SQLITE_BUSY”重试逻辑
- 写入顺序天然就是时间顺序,便于调试
- 客户端场景的数据库负载远未到需要并行 SQLite 的程度
- 代价:读取也需要异步回调,增加了 API 复杂度
- 背景:Qt 6 主推 QML,Widgets 被视为”legacy”
- 决策:使用 Qt Widgets
- 理由:
- 自定义控件(消息气泡、仪表盘)用
QPainter::paintEvent 比 QML Canvas 更可控
- 与 C++ 核心库零距离——Model 可以直接是 C++ STL 容器的包装
- 需求文档要求”QTGUI+控件开发”,Widgets 是 Qt GUI 的本体
- QML 需要额外的
qmlRegisterType 绑定层,增加耦合
10. 构建系统设计
10.1 CMake 结构
# client/CMakeLists.txt — C++ 桌面客户端
cmake_minimum_required(VERSION 3.20)
project(YunRong VERSION 0.1.0 LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
# 第三方依赖 (FetchContent)
include(FetchContent)
FetchContent_Declare(nlohmann_json GIT_REPOSITORY https://github.com/nlohmann/json.git ...)
FetchContent_Declare(spdlog GIT_REPOSITORY https://github.com/gabime/spdlog.git ...)
# 子目录
add_subdirectory(src/core) # 核心库 (无 Qt GUI)
add_subdirectory(src/gui) # GUI 库 (依赖 Qt Widgets)
add_subdirectory(src/app) # 可执行文件
add_subdirectory(tests) # 测试
# Mock Server 是独立 CMake 项目 (mock/CMakeLists.txt)
10.2 平台适配宏
# cmake/Platform.cmake
if(WIN32)
target_compile_definitions(core PRIVATE PLATFORM_WINDOWS)
target_link_libraries(core PRIVATE ws2_32 crypt32)
elseif(UNIX AND NOT APPLE)
target_compile_definitions(core PRIVATE PLATFORM_LINUX)
target_link_libraries(core PRIVATE pthread dl)
endif()
附录 A — 术语表
| 术语 | 说明 |
|---|
| ADR | Architecture Decision Record,架构决策记录 |
| WAL | Write-Ahead Logging,SQLite 的并发写模式 |
| Proactor | 异步 IO 模式——OS 完成后通知,与 Reactor(就绪通知)相对 |
| QueuedConnection | Qt 跨线程信号槽连接类型,槽函数在接收者线程的事件循环中执行 |
| Event Loop | Qt 主线程事件循环,QWebSocket 和 QNetworkAccessManager 均在其上异步运行 |
附录 B — 文档修订记录
| 版本 | 日期 | 作者 | 变更说明 |
|---|
| v0.1 | 2025-01 | — | 初稿,完成全部章节 |