NEVO 项目技术架构文档
NEVO 是一款低延迟加密 VoIP 通讯系统,采用 C++20 构建跨平台客户端/服务端架构。 项目支持桌面端(Windows / Linux / macOS)、移动端(Android / iOS)以及 Web 管理面板, 提供高质量实时语音通讯能力,具备端到端加密、NAT 穿透和可扩展频道系统。
📌 快速导航
1. 项目概述
NEVO 是一款低延迟加密 VoIP 通讯系统,采用 C++20 构建跨平台客户端/服务端架构。项目支持桌面端(Windows / Linux / macOS)、移动端(Android / iOS)以及 Web 管理面板,提供高质量实时语音通讯能力,具备端到端加密、NAT 穿透和可扩展频道系统。
核心特性
| 特性 | 描述 |
|---|---|
| 🎙️ 低延迟音频 | miniaudio 采集/播放 + Opus 编解码器,带带内 FEC 前向纠错 |
| 🔐 加密语音 | XChaCha20-Poly1305 AEAD 加密,自动密钥轮换 |
| 🌐 NAT 穿透 | STUN 绑定 + TCP 回退语音隧道 |
| 📡 频道系统 | 层次化频道树 + 权限控制 |
| 🖥️ 跨平台桌面端 | Qt 6 Widgets UI,可停靠面板 |
| 📊 服务端仪表盘 | 实时会话监控、用户管理 |
| 📱 移动端支持 | 原生 Android (Kotlin) + iOS (Swift) 客户端 |
项目目录结构
NEVO/
├── cmake/ # CMake 辅助模块
├── proto/ # Protobuf 协议定义
│ └── generated/ # 手写 C++ protobuf 替换头文件
├── 3rdparty/ # 嵌入式依赖 (miniaudio, spdlog stub)
├── src/
│ ├── core/ # 共享核心库 (音频/协议/权限/通用)
│ ├── network/ # 网络库 (TCP/UDP/加密/NAT/SSL)
│ ├── client/ # 客户端应用
│ ├── server/ # 服务端应用
│ └── ui/ # 客户端 UI (Qt 6)
├── mobile/
│ ├── android/ # Android 客户端
│ └── ios/ # iOS 客户端
├── web/ # Web 管理面板
├── website/ # Cloudflare Pages 网站
├── tests/ # 单元测试 & 集成测试 (GTest)
├── docs/ # 项目文档
├── scripts/ # 辅助脚本
├── installer/ # 安装包 (NSIS)
├── bgm/ # 背景音乐文件
├── Dockerfile # Docker 多阶段构建
├── docker-compose.yml # Docker 编排配置
└── CMakeLists.txt # 顶层构建配置
2. 技术架构
2.1 整体架构图
2.2 技术栈总览
| 层级 | 技术选型 | 版本要求 |
|---|---|---|
| 核心语言 | C++20 | MSVC 2022 / GCC 12+ / Clang 15+ |
| 构建系统 | CMake | 3.21+ |
| 桌面 UI | Qt 6 (Widgets) | Core + Widgets 模块 |
| 异步 I/O | Boost.Asio (协程) | 1.80+ |
| 音频引擎 | miniaudio + Opus | miniaudio (单头文件嵌入) |
| 加密库 | libsodium | XChaCha20-Poly1305 AEAD |
| 通信协议 | Protocol Buffers | proto3 语法 (手写头文件) |
| 数据存储 | SQLite3 | 服务端持久化 |
| 日志系统 | spdlog | 嵌入式 stub + fmt-style |
| 容器化 | Docker + Docker Compose | 多阶段构建 (Ubuntu 22.04) |
| CI/CD | GitHub Actions | 自动化构建/测试 |
| 测试框架 | Google Test (GTest) | v1.14.0 |
| 包管理 (C++) | CMake FindPackage + FetchContent | 自动降级 stub |
| 包管理 (桌面) | Python pip + PyQt5 | Python 3.8+ |
| 移动平台 | Android Gradle KTS / iOS SPM | Android SDK 33+, iOS 15+ |
2.3 构建系统
项目使用 CMake 3.21+ 统一管理所有 C++ 模块的构建。整体采用模块化设计,每个模块可独立编译并自动检测依赖,依赖缺失时优雅降级为 stub 实现。
条件编译标志
| 宏定义 | 影响范围 | 缺失时的降级行为 |
|---|---|---|
NEVO_HAS_BOOST | 网络模块 | 跳过网络/客户端模块 (协程 stub) |
NEVO_HAS_OPUS | 音频编解码 | Opus 编解码返回静音 |
NEVO_HAS_SODIUM | 语音加密 | 明文传输 (无加密) |
NEVO_HAS_SQLITE | 服务端数据库 | 纯内存模式 (无持久化) |
NEVO_HAS_OPENSSL | TLS 传输 | 明文 TCP 传输 |
NEVO_HAS_QT | 桌面 UI | 跳过 UI 模块 |
构建命令
cmake -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build --parallel
cmake -B build -DBUILD_TESTING=ON
cmake --build build --parallel
ctest --test-dir build --output-on-failure
cmake -B build -DBUILD_TESTING=ON -DENABLE_COVERAGE=ON
2.4 通信协议
协议层基于 Protocol Buffers proto3 语法定义,包含控制协议和语音协议两大类别。
| 文件 | 包名 | 用途 |
|---|---|---|
proto/common.proto | nevo.common | 用户/频道信息、状态枚举、结果码 |
proto/control.proto | nevo.control | 控制消息:登入、频道管理、权限同步 |
proto/voice.proto | nevo.voice | UDP 语音包头:序列号、加密元数据、FEC |
关键协议结构
enum ResultCode {
OK = 0; ERROR_AUTH_FAILED = 2; ERROR_PERMISSION_DENIED = 3;
ERROR_CHANNEL_NOT_FOUND = 4; ERROR_TIMEOUT = 8; ERROR_CRYPTO_ERROR = 10;
}
message VoicePacketHeader {
uint32 sequence_number = 1; uint64 sender_id = 2;
uint64 channel_id = 3; uint32 timestamp = 4;
bool last_frame = 5; uint32 fec_payload_size = 6;
bytes nonce = 7; bytes auth_tag = 8;
bool tcp_tunnel = 9;
}
3. 功能模块说明
3.1 核心模块 (nevo_core)
核心模块是所有上层模块的公共依赖,提供音频处理、协议编解码、权限系统和通用工具。
| 子模块 | 路径 | 职责 |
|---|---|---|
audio/ | src/core/audio/ | AudioEngine、Opus 编解码、JitterBuffer、AudioMixer、VAD 静音检测 |
common/ | src/core/common/ | Result<T> 错误处理、Logger 日志、Types 基础类型 |
protocol/ | src/core/protocol/ | PacketCodec 协议编解码、帧编码 |
permission/ | src/core/permission/ | 频道权限系统 |
音频处理流水线
3.2 网络模块 (nevo_network)
网络库提供异步网络通信基础设施,核心设计基于 Boost.Asio 协程实现高性能 I/O。
| 组件 | 功能 |
|---|---|
| TcpConnection | 异步 TCP 连接 + 帧协议 |
| UdpSocket | 异步 UDP 套接字 |
| VoiceCrypto | 语音加密/解密,自动密钥轮换 |
| NatTraversal | STUN 客户端,NAT 类型探测 |
| SslWrapper | OpenSSL TLS 加密传输 |
tcp_tunnel = true),语音数据通过已建立的 TCP 连接传输。
3.3 客户端模块 (nevo_client)
桌面客户端采用 Python (PyQt5) + C++ 核心库 的混合架构。
| 类 | 职责 |
|---|---|
ClientCore | 客户端生命周期管理、状态机 |
NetworkManager | 客户端网络协调,管理 TCP/UDP 连接 |
AudioInput / AudioOutput | 音频采集和播放封装 |
src/client/
├── include/nevo/client/
│ ├── ClientCore.h # 客户端核心接口
│ └── NetworkManager.h # 网络管理器接口
├── src/
│ ├── ClientCore.cpp # 客户端状态机实现
│ ├── NetworkManager.cpp # 网络管理器实现
│ └── AudioInput/Output # 音频 I/O
├── gui_python/
│ └── main.py # Python 桌面 GUI 入口
└── CMakeLists.txt
3.4 服务端模块 (nevo_server)
服务端是系统的核心中枢,负责用户认证、频道管理、音频路由和状态持久化。
| 类 | 职责 |
|---|---|
ServerCore | 服务端生命周期,启动/停止/健康检查 |
ClientSession | 每个客户端的连接处理器,管理独立会话 |
Database | SQLite3 持久化层,用户数据存储 |
启动配置
# CLI 方式
./nevo_server --tcp-port 24430 --udp-port 24431 --db server.db --threads 4 --log-level info
# JSON 配置文件 (server_config.json)
{
"tcp_port": 24430, "udp_port": 24431, "db_path": "server.db",
"threads": 4, "log_level": "info", "server_name": "NEVO Server",
"max_users": 100, "welcome_message": "Welcome to the NEVO server!"
}
# Docker Compose 部署
docker compose up -d
3.5 UI 模块 (nevo_ui)
桌面客户端 UI 基于 Qt 6 Widgets 实现。
| 组件 | 功能 |
|---|---|
MainWindow | 主窗口,包含可停靠面板 (QDockWidget) |
ChannelTreeModel | 频道层次树数据模型 |
UserListModel | 用户列表数据模型 |
ConnectionBar | 连接状态栏和连接对话框 |
3.6 移动端
移动端为原生实现,分别对应 Android (Kotlin) 和 iOS (Swift),通过 JNI 和 C Interop 桥接 C++ 核心逻辑。
mobile/android/app/src/main/java/com/nevo/voip/
├── core/
│ ├── protocol/
│ │ ├── MessageType.kt # 消息类型枚举
│ │ └── ProtocolSerializer.kt # 二进制序列化器
│ └── update/
│ └── UpdateManager.kt # 应用更新管理器
mobile/ios/NevoClient/
├── Protocol/
│ └── WireFormat.swift # 网络数据包格式定义
└── Package.swift # Swift Package Manager 配置
3.7 Web 管理面板
Web 管理面板用于远程服务器监控和管理,采用轻量级前后端分离架构。
| 组件 | 技术 | 功能 |
|---|---|---|
| 前端 | HTML5 / CSS3 / Vanilla JS | 仪表盘、会话管理、频道、性能监控、系统配置 |
| 后端 | Python (server.py) | API 服务、WebSocket 实时推送 |
| 网站 | Cloudflare Pages | 静态网站托管 |
| 字体 | Google Fonts | Inter (UI) + JetBrains Mono (代码) |
4. 页面结构设计
Web 管理面板采用 侧边栏 + 主内容区 的经典管理后台布局。
Web 管理面板导航结构
NEVO 管理面板
├── 📊 仪表盘 (Dashboard)
│ ├── 服务器运行状态概览
│ ├── 在线用户数 / 活跃频道数
│ └── 实时带宽/延迟图表
├── 👥 会话管理 (Sessions)
│ ├── 当前连接用户列表
│ ├── 用户踢出/静音/封禁操作
│ └── 会话详情查看
├── 📡 频道 (Channels)
│ ├── 层次化频道树
│ ├── 频道创建/编辑/删除
│ └── 权限设置
├── 📈 性能监控 (Metrics)
│ ├── CPU/内存/网络占用图表
│ ├── 音频包延迟分布
│ └── 丢包率统计
├── ⚙️ 系统配置 (Config)
│ ├── 服务器参数配置
│ ├── 日志级别调整
│ └── 配置导入/导出
└── 🖥️ 服务器控制 (Server)
├── 启动/停止/重启
├── 运行日志查看
└── 健康检查状态
桌面客户端界面结构
NEVO 桌面客户端 (Qt 6)
├── MainWindow
│ ├── QDockWidget: 频道面板 (ChannelTreeModel)
│ ├── QDockWidget: 用户面板 (UserListModel)
│ ├── ConnectionBar: 连接状态 + 设置
│ └── 中央内容区
5. 交互流程
客户端连接 → 语音通讯完整流程
连接生命周期状态机
DISCONNECTED
│ TCP 连接成功
▼
CONNECTING
│ TLS 握手完成
▼
AUTHENTICATING
│ 凭证验证通过
▼
ONLINE ←──────────────── 空闲/活跃状态
││
│├─ 加入频道 → IN_CHANNEL (开始语音数据流)
││
│└─ NAT 穿透 → UDP 直连 / TCP 隧道 → 语音收发
│
└── 断线/超时 → DISCONNECTED (释放资源)
关键场景流程
| 场景 | 触发条件 | 处理流程 |
|---|---|---|
| 用户登入 | TCP 连接 + 发送认证请求 | 验证用户名 → 分配 Session → 同步频道列表 → 通知在线用户 |
| 加入频道 | 权限验证通过 | Channel 添加用户 → 通知频道内用户 → 音频流切换 |
| 开始说话 | VAD 检测到语音 / PTT 按下 | 音频采集 → Opus 编码 → 加密 → UdpSocket 发送 → 服务端转发 |
| NAT 穿透 | UDP 尝试失败 | STUN 绑定 → 若成功 UDP 直连,失败 TCP 隧道回退 |
| 密钥轮换 | 定时触发 / 包计数达阈值 | 服务端生成新密钥 → 广播至频道成员 → 切换加密密钥 |
| 服务器关闭 | 管理员操作 / Docker stop | 通知所有客户端 → 保存 DB → 关闭监听 → 清理资源 |
6. 响应式设计规范
Web 管理面板 — 断点策略
| 断点 | 设备类型 | 布局 |
|---|---|---|
≥ 1024px | 桌面端 | 侧边栏固定 + 主内容区自适应 |
768px — 1023px | 平板端 | 折叠式侧边栏 (汉堡菜单开关) |
< 768px | 手机端 | 隐藏侧边栏,全屏主内容区 |
响应式设计要点
- CSS Flexbox + Grid:主布局使用 Flexbox 实现弹性布局
- 移动端菜单:通过
#menu-open/#menu-close按钮切换侧边栏显示 - 数据表格:小屏幕下使用
overflow-x: auto水平滚动 - 图表组件:SVG 自适应容器宽度,
viewBox保持比例 - 触碰目标:移动端按钮最小 44×44px,满足 WCAG 2.1 AA
- 辅助功能:提供
.skip-link键盘跳过导航、aria-*属性标注
桌面客户端 — 跨平台适配
| 平台 | UI 框架 | 适配策略 |
|---|---|---|
| Windows | Qt 6 Widgets | 原生 Windows 渲染,DPI 自动缩放 |
| macOS | Qt 6 Widgets | macOS 风格渲染,Retina 高 DPI 支持 |
| Linux | Qt 6 Widgets | 跟随系统主题 (GTK/Qt5ct) |
7. 性能优化策略
音频流水线优化
| 优化点 | 策略 | 效果 |
|---|---|---|
| Opus 编码帧 | 20ms 帧长,带内 FEC | 带宽 6-510 kbps 自适应,单包丢失可恢复 |
| JitterBuffer | 自适应去抖 + 丢包重排 | 网络抖动 ≤50ms 无感知,≤150ms 可接受 |
| AudioMixer | 多路混音 + 音量归一化 | 支持 64 路并发,3ms 混音开销 |
| VAD 静音检测 | 未说话时不编码发送 | 闲置带宽降低 70-90% |
| 内存池 | AudioMemoryPool 预分配 | 避免运行时动态分配,零堆碎片 |
网络层优化
| 优化点 | 策略 |
|---|---|
| 异步 I/O | Boost.Asio 协程,单线程事件循环驱动多连接 |
| 零拷贝 | 数据包内存池复用,避免内核态 memcpy |
| TCP_NODELAY | 禁用 Nagle 算法,即时发送小包 |
| UDP 批量发送 | sendmmsg 批量发送,减少系统调用次数 |
服务端优化
| 优化点 | 策略 |
|---|---|
| 多线程 | --threads N 配置工作线程数,I/O 与业务分离 |
| SQLite WAL | WAL 模式写入,支持并发读 + 串行写 |
| Docker 资源限制 | CPU 2 核 / 内存 512M 上限,健康检查探活 |
| 日志轮转 | json-file driver,单文件 20M,保留 5 个历史 |
8. 浏览器兼容性要求
Web 管理面板 — 目标浏览器
| 浏览器 | 最低版本 | 说明 |
|---|---|---|
| Google Chrome | 90+ | 推荐 — 完整支持所有 CSS/JS 特性 |
| Microsoft Edge | 90+ | Chromium 内核,与 Chrome 等价 |
| Mozilla Firefox | 88+ | 支持所有现代特性 |
| Safari (macOS/iOS) | 14+ | WebKit 内核 |
依赖的 Web 平台特性
- CSS Grid + Flexbox — 所有目标浏览器原生支持
- CSS Custom Properties (
var()) — 主题变量 - SVG inline — 导航图标内嵌 SVG
- Fetch API — 与服务端 API 通信
- Google Fonts — Inter + JetBrains Mono 字体 (有回退字体栈)
- 无外部 JS 框架依赖 — 纯 Vanilla JS,降低兼容性风险
桌面客户端 — 操作系统兼容性
| 操作系统 | 最低版本 | 编译工具 |
|---|---|---|
| Windows | Windows 10 (1809+) | MSVC 2022 |
| macOS | macOS 12 (Monterey) | Clang 15+ |
| Linux (Debian) | Debian 11 / Ubuntu 22.04 | GCC 12+ / glibc 2.34+ |
| Linux (其他) | glibc 2.34+, Qt 6 | RPM/DEB 包分发 |
移动端兼容性
| 平台 | 最低版本 | 构建工具 |
|---|---|---|
| Android | Android 13 (API 33) | Gradle KTS + NDK 26 |
| iOS | iOS 15 | Xcode 14 + Swift 5.7 |
9. 已知问题与解决方案
| 编号 | 分类 | 描述 | 影响范围 | 严重程度 | 状态 |
|---|---|---|---|---|---|
| #1 | 网络 | 对称型 NAT (Symmetric NAT) 环境下 STUN 穿透成功率极低,语音回退到完全依赖 TCP 隧道 | 企业网络 / 校园网用户 | 🟡 中等 | 已知 — TCP 隧道兜底 |
| #2 | 协议 | Protobuf 采用预生成的手写头文件 (proto/generated/) 替代标准 protoc 编译,协议版本更新需同步手动修改 |
协议迭代 | 🟡 中等 | 已知 — 脚本同步辅助 |
| #3 | 音频 | iOS 平台蓝牙耳机音频路由切换延迟偏高 (300-500ms),在锁屏状态下音频采集可能中断 | iOS 蓝牙用户 | 🟡 中等 | 持续优化中 |
| #4 | 构建 | Android NDK 跨平台编译 miniaudio 时需手动处理 NEON 指令集优化标志 | Android ARM 构建 | 🟢 轻微 | 文档已注明 |
| #5 | UI | Qt 6 在 Linux Wayland 下部分 dock 面板拖拽行为异常 | Linux Wayland 用户 | 🟢 轻微 | 建议 X11 模式运行 |
常见问题排查
1. 检查服务器 TCP 24430 端口是否开放
nc -zv SERVER_IP 244302. 检查防火墙规则是否放行 TCP 24430 和 UDP 24431
3. 检查 Docker 容器健康状态
docker compose ps4. 查看服务器日志
docker compose logs -f nevo-server
— 增加 JitterBuffer 缓冲大小 (默认 60ms)
— 确认 Opus 编码器未使用 stub 降级
— 检查 CPU 利用率,音频编码需要 1 核心的 15-20%
10. 开发规范与指南
代码规范
- C++ 命名:类名 PascalCase (
AudioEngine),文件名 PascalCase (AudioEngine.h),命名空间 snake_case (nevo::audio) - 当前测试框架为 Google Test (GTest v1.14.0),测试目录
tests/包含:Result<T>错误处理单元测试- Channel 频道管理单元测试
- Permission 权限系统单元测试
- Opus 编解码器集成测试
- JitterBuffer 去抖缓冲测试
- AudioMixer 多路混音测试
- AudioMemoryPool 内存池测试
- TcpConnection 帧协议测试
- VoiceCrypto 加解密测试
- NatTraversal STUN 协议测试
- Server 服务端集成测试
CMake 依赖管理策略
项目遵循 FindPackage → vcpkg CONFIG → stub 降级 的三级依赖查找策略:
- FindPackage:优先使用系统已安装的库
- vcpkg / pkg-config:使用包管理器提供的版本
- FetchContent:自动下载 (仅限 GTest 等测试依赖)
- Stub 降级:全部缺失时,编译不含该功能的精简版本
📌 文档维护说明本文档应与项目代码同步更新。每当以下内容发生变化时,需更新本文档中对应章节:
1. 新增/删除功能模块 → 更新第3章
2. 技术栈升级 (库版本变更) → 更新第2.2节
3. Web 页面重构 → 更新第4章
4. 新增已知问题或问题修复 → 更新第9章
5. 构建/部署流程变更 → 更新第2.3节和第10章