架构设计¶
系统概述¶
DraARL Server 是一个专业的数字无线电实时通信平台,采用前后端分离架构,核心是一个基于自研 DraARLv1 协议的 UDP 语音转发引擎。
整体架构¶
架构分层说明¶
| 层级 | 说明 |
|---|---|
| 客户端层 | 支持多种设备接入:ESP32硬件设备、Android/iOS移动客户端、Windows PC、Web浏览器、对讲桥接器 |
| 网络接入层 | UDP Server处理硬件设备通信,HTTP Server提供REST API,WebSocket处理浏览器实时通信 |
| 业务逻辑层 | 核心业务模块:认证、设备管理、群组管理、语音引擎、通信录制、APRS/AI服务 |
| 数据存储层 | MySQL主数据库、Redis Token存储、统一 Storage 对象存储、内存多级缓存 |
| 外部服务 | APRS-IS网络、Keycloak SSO、SMTP邮件、其他DraARL服务器 |
UDP 服务器核心¶
UDP 服务器是系统的核心,负责处理所有 UDP 设备的通信。
核心模块说明¶
| 模块 | 文件 | 职责 |
|---|---|---|
| 数据包接收 | server.go |
UDP数据包接收、限速器(150pps)、PROXY Protocol支持 |
| 设备认证 | auth.go |
设备密码认证(AES解密+bcrypt)、阶梯封禁(10s/30s/60s/300s) |
| JWT认证 | jwt_auth.go |
幽灵设备JWT Token认证 |
| 幽灵设备 | ghost.go |
UDP幽灵设备管理(Android/iOS/Windows/macOS) |
| 半双工仲裁 | half_duplex.go |
严格半双工:同一转发域同时只允许一个说话人,900ms超时 |
| 群组互联 | group_link.go |
虚拟互联组缓存,跨群组语音/文本转发 |
| 通信录制 | comm_recorder.go |
音频会话缓冲、通过 Storage 批量上传、数据库同步 |
| 设备绑定 | pending_device.go |
6位动态码生成、MAC绑定、配置下发 |
| 配置同步 | config.go |
TLV格式设备配置同步 |
认证架构¶
平台采用三轨制认证体系,根据设备类型自动选择认证方式。
认证方式对比¶
| 认证方式 | 适用设备 | SSID范围 | 认证凭证 | 说明 |
|---|---|---|---|---|
| 普通设备认证 | ESP32、桥接器 | 1-99, 106-254 | 设备密码 | AES加密存储,bcrypt验证 |
| 幽灵设备认证 | App/PC客户端 | 101-105 | JWT Token | 复用Web登录,无需预共享密钥 |
| 动态码绑定 | 新设备首次上线 | 1-99, 106-254 | 6位动态码 | 5分钟有效期,单次使用 |
在线冲突处理¶
| 设备类型 | 冲突策略 | 说明 |
|---|---|---|
| 普通UDP设备 | 同用户同SSID只允许一台 | 同MAC可快速重连 |
| 幽灵设备(App/PC) | 按客户端实例和临时 Session 隔离 | 同账号同平台可多端;同一安装实例重连只替换自身旧 Session |
| WebSocket(Web) | 每个浏览器安装实例独立在线 | 多标签页/多浏览器不会覆盖其他移动端或浏览器实例 |
幽灵 Session 采用“多收单发”:每个 Session 只有一个发送频道,同时可订阅最多 16 个接收频道。旧 raw-JWT/无实例 ID 客户端不再支持。标准 UDP 实体设备不进入该 Session 模型,继续保持 owner_id + ssid 单端约束。
语音转发架构¶
半双工仲裁机制¶
- 同一转发域内,同一时刻只允许一个说话人
- 转发域计算:通过BFS图遍历,计算群组和虚拟互联组的连通域
- 发言权获取:设备发送语音包时,检查该转发域是否有人在说话
- 超时释放:900ms无新语音包,自动释放发言权
语音转发流程¶
- 设备A发送Opus语音包 (60ms帧)
- 服务器认证检查
- 半双工仲裁获取发言权
- 群组路由查找目标设备
- 转发到群组内所有在线设备
- 如果有虚拟互联组,同时转发到关联群组
群组互联架构¶
虚拟互联组特性¶
- 自动转发:语音/文本消息自动转发到所有关联的目标群组
- 多级互联:支持A↔B↔C多级互联
- 防循环转发:内置机制防止消息在互联组间循环
- 管理员配置:仅管理员可创建和管理虚拟互联组
缓存架构¶
多级缓存策略¶
| 层级 | 存储 | 说明 |
|---|---|---|
| L1 | 内存缓存 | 分片锁 + RCU模式,读无锁写时复制 |
| L2 | Redis | Refresh Token、登录失败和注册/验证码保护;release 构建必需,development/test 可内存降级 |
| L3 | MySQL | 全量数据持久化 |
| L4 | Storage(可选) | local、MinIO 或 S3 兼容对象存储:头像、音频、固件、资源 |
缓存特点¶
- 分片锁:32分片减少锁竞争
- RCU模式:群组缓存采用读无锁、写时复制
- 命中率监控:实时统计缓存效果
- 自动过期:TTL机制自动清理
HTTP/WebSocket 服务器¶
基于 Gin 框架的 HTTP 服务器,提供 REST API 和 WebSocket 服务。
中间件层¶
| 中间件 | 说明 |
|---|---|
| CORS | 跨域资源共享,Origin白名单 |
| JWT | Token认证,支持Header和Cookie |
| Rate Limit | 接口限流,防止滥用 |
| Origin Check | WebSocket来源检查 |
路由层¶
| 路径 | 说明 |
|---|---|
/api/* |
REST API接口 |
/ws |
WebSocket实时通信 |
/* |
静态文件服务(嵌入模式) |
部署架构¶
单机部署¶
适用于小规模部署和开发测试:
- 单个Go二进制提供所有服务
- MySQL + Redis + Storage(local 或对象存储,可选)
- 支持嵌入前端,单文件部署
中心到中心部署¶
当前 dev 以独立主站为部署单位。每个主站连接自己的 MySQL、Redis、HTTP、对象存储和
IP 数据库;Interconnect.Enabled=true 后,中心间准入复用 HTTP/HTTPS 服务,实时音频
复用 System.Port 主 UDP 监听,不增加第三个互联端口。
- A 生成绑定本地群组和收发策略的一次性邀请 Token。
- B 使用 Token、A 的 HTTP/HTTPS 地址、本地群组和本地收发策略完成准入。
- HTTP 准入使用 Token verifier 的 HMAC 证明校验请求和响应,双方用 verifier 与 session ID 独立派生 AES-GCM UDP 会话密钥;两端用户、设备、权限和数据库保持独立。
- 远端音频在本地群组中以
Server-*虚拟设备出现,并继续经过本地 fan-out 和半双工检查。 GET /api/access-points目前只发布本主站中心入口,为后续动态端口和多个收发器保留接口。
旧的无数据库边缘运行时及其 Type 0/TLS 节点控制能力只保留在 edge 分支,不属于
dev 的启动路径。数据库、Redis 和对象存储的高可用仍由部署平台单独提供;服务端不会
把多个 HTTP/UDP 进程自动组成共享状态集群。完整的中心互联数据面和准入语义见
多中心群组互联设计。
技术栈总结¶
| 层级 | 技术 | 说明 |
|---|---|---|
| 前端 | React 19 + TypeScript + Vite 7 + MUI 7 | 现代化前端框架 |
| HTTP框架 | Gin 1.12 | 高性能HTTP框架 |
| ORM | GORM 1.31 | 数据库ORM |
| WebSocket | Gorilla WebSocket | WebSocket支持 |
| 数据库 | MySQL 5.7+ / MariaDB 10.3+ | 主数据库 |
| 缓存 | Redis 6.0+ | release 构建的 Token 和共享认证保护存储;development/test 可降级 |
| 对象存储 | local、MinIO、S3/R2/COS/OSS(可选) | 统一存储抽象、预签名上传/下载 |
| 认证 | JWT v5 + AES + bcrypt | 多种认证方式 |
| 音频编码 | Opus 16K | 语音编解码 |
| 协议 | DraARLv1 | 自研UDP协议 |