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