6.4 KiB
6.4 KiB
DbusSmsForward Debian 深度重构设计
现状判断
当前公开仓库并不是 OpenWRT 专用实现,实际上已经围绕 Debian + ModemManager + DBus 工作。但它离“可在 Debian 上长期稳定使用”的目标还有明显差距,主要是工程结构过于原始。
当前架构主要问题
-
纯交互式入口
Program.cs通过Console.ReadLine()完成模式选择、渠道选择、首次配置。- 这导致它无法无交互运行,不适合 systemd、daemon、自启动、容器化或远程运维。
-
配置模型不适合服务部署
ConfigHelper只读写AppContext.BaseDirectory/appsettings.json。- 这意味着配置和程序强绑定,无法自然放到
/etc/dbussmsforward/、~/.config/或通过环境变量注入。 - 也没有配置校验、默认值归一化、密钥与普通配置分层。
-
发送渠道实现高度耦合
ProcessChoise既处理交互,又决定启用哪些发送器,又触发各发送器自己的“首次输入配置流程”。- 每个
SendBy*类都直接读配置、拼接 HTTP、同步阻塞调用、直接向控制台打印结果。 - 不利于扩展新渠道,也无法做统一重试、超时、日志与错误处理。
-
HTTP/证书处理有风险
HttpHelper全局使用DangerousAcceptAnyServerCertificateValidator。- 这在 Debian 长期运行场景下非常危险,等于默认跳过 TLS 校验。
-
同步阻塞 + 弱错误处理
- 大量
.Result阻塞异步调用。 - 错误处理基本是
catch(Exception ex) Console.WriteLine(...),缺乏分级日志和可观测性。
- 大量
-
项目目标平台过窄
DbusSmsForward.csproj固定RuntimeIdentifiers=linux-musl-arm64- 启用
PublishAot=true TargetFramework=net10.0- 这对 Debian x64/arm64 通用部署非常不友好,也加大本地构建门槛。
-
缺少 daemon/service 概念
- 没有
DaemonConfig这种运行期控制配置。 - 没有 systemd unit、工作目录规范、日志规范、停止信号处理、启动健康检查。
- 没有
-
历史记忆中的配置未在公开仓库中体现
- 本地历史记忆提到
AutmanPushConfig与DaemonConfig。 - 当前公开仓库未包含这两项,说明需要在本次 Debian 重构中主动引入统一的新配置结构。
- 本地历史记忆提到
Debian 化重构目标
核心目标
将项目改造成:
- 非交互式配置驱动
- 可作为 systemd 服务运行
- 支持 Debian x64 / arm64
- 保留现有发送能力
- 增加统一配置模型与运行控制能力
- 为未来新增 Autman Push / Webhook / 更多通知渠道预留扩展点
建议的新架构
1. 宿主层改为 Generic Host
用 .NET Generic Host 替代当前顶层裸 Program.cs:
Host.CreateApplicationBuilder(args)IHostedService/BackgroundServiceILogger<T>IOptions<T>/ 配置绑定ConsoleLifetime/Systemd集成
建议拆成以下角色:
SmsForwardWorker:监听 ModemManager 短信事件并派发SmsSendService:主动发送短信ModemManagerClient:封装 DBus/ModemManager 访问NotificationDispatcher:统一调度多个通知器INotificationSender:每种发送渠道一个实现
2. 配置体系重构
建议引入新的配置根模型,例如:
DaemonConfigModemConfigForwardingConfigNotificationTargetsAutmanPushConfigWebhookConfigTelegramConfigEmailConfigShellConfig
并支持以下优先级:
/etc/dbussmsforward/appsettings.json./appsettings.json- 环境变量(如
DBUSSMSFORWARD__...) - 命令行参数
3. 命令模式替代交互模式
建议把交互式入口改成命令式:
dbussmsforward rundbussmsforward send --to 138... --text "..."dbussmsforward validate-configdbussmsforward print-sample-config
保留旧参数 -fE/-fP/.../-sS 作为兼容层,但内部只转换成新命令,不再触发交互式流程。
4. 发送渠道抽象
定义统一接口:
INotificationSenderstring NameTask SendAsync(SmsMessage sms, CancellationToken ct)
每个渠道单独实现:
EmailNotificationSenderPushPlusNotificationSenderTelegramNotificationSenderDingTalkNotificationSenderBarkNotificationSenderWeComNotificationSenderShellNotificationSenderAutmanPushNotificationSender(新增)
由 NotificationDispatcher 统一完成:
- 启用判断
- 超时控制
- 错误隔离
- 日志记录
- 可选并发发送
5. 安全与可靠性修复
- 默认启用 TLS 证书校验
- 仅在配置显式允许时跳过证书校验
- 用
HttpClientFactory替换手写同步HttpClient - 所有外部调用改为 async/await
- 增加超时、重试(至少对 HTTP 类通知)
- 用结构化日志替代
Console.WriteLine
6. 构建与发布策略调整
建议不要默认强绑 NativeAOT。 更适合 Debian 的策略:
- 默认:
net8.0或net9.0framework-dependent / self-contained - 可选:额外保留 AOT 发布 profile
- RIDs 至少支持:
linux-x64linux-arm64
这样更利于 Debian VPS/小主机/工控盒子直接部署。
建议分阶段实施
Phase A:最小可用 Debian 服务化
- 改造配置加载
- 去掉首次运行交互依赖
- 引入 run/send/validate-config 命令
- 统一日志
- 补 systemd unit 示例
Phase B:通知通道抽象化
- 拆
SendBy*为 sender 实现 - 引入 dispatcher
- 补
AutmanPushConfig - 允许多渠道并行转发
Phase C:兼容与增强
- 保留旧 CLI 参数兼容
- 支持环境变量覆盖
- 支持跳过证书校验的显式开关
- 输出 Debian 部署文档
本次实际重构建议
如果现在开始直接动代码,我建议这样做:
- 新建
Configuration/、Services/、Notifications/、Models/目录 - 引入新的配置类,其中补上:
DaemonConfigAutmanPushConfig
- 重写
Program.cs为 host + command 模式 - 保留现有
ModemManagerHelper,但包一层服务接口 - 逐步把
SendBy*改为异步 sender - 补
appsettings.example.json - 补
dbussmsforward.service - 最后整理 README 的 Debian 使用方式
结论
这次重构的重点不是“把 OpenWRT 代码移植到 Debian”,而是: 把一个能在 Debian 上跑的个人脚本式 .NET 工具,重构成一个适合 Debian 长期托管运行的服务程序。
下一步应进入 t3:实施重构、补齐配置/服务化/兼容逻辑。