feat: 落地 V1 全部源码 — WebSocket 通知 + 应用内历史查看

17 个源文件 + .gitignore + 默认 config.json 模板,严格按方案文档第 6 节实现。

用户核心场景:

- Windows 接收 Gotify 通知(WS /stream → AppNotificationBuilder)

- 应用内查看历史消息(打开 MainWindow 触发 GetRecentMessagesAsync,实时通过 MessageReceived 事件追加)

- 列表条目双击打开 extras.client::notification.click.url

关键变更点:

- GotifyMessage.Extras 类型由 Dictionary<string,object> 改为 Dictionary<string,JsonElement>,避免 System.Text.Json 反序列化时丢失嵌套结构

- 新增 HistoryConfig.ViewerLimit(默认 50,UI 硬上限 200)

- GotifyApiService.GetRecentMessagesAsync:since=0 拉最近 N 条,OrderByDescending(Id) 保证顺序

- GotifyWebSocketService 新增 MessageReceived 事件,MainWindow 用 Dispatcher.Invoke 切回 UI 线程追加

- NotificationService.AddArgument('url=...') 透传 click URL 给 OnNotificationInvoked

- MainWindow.xaml 增加 ListView + 刷新按钮,使用 ObservableCollection<GotifyMessage>

- 默认 config.json 用 https://gotify.example.com 占位 URL,ClientToken 留空,首启动自动写入 %LOCALAPPDATA%

依赖:Microsoft.WindowsAppSDK 2.4.0(方案文档固定版本)。

构建:本机 .NET 8 SDK 未安装,build 待用户在装好 SDK 后执行: dotnet restore && dotnet build -c Release
This commit is contained in:
2026-09-06 18:44:55 +08:00
parent 4b7f3a383c
commit c2f44767a6
19 changed files with 1401 additions and 2 deletions
+13 -2
View File
@@ -2,6 +2,16 @@
Windows Gotify Agent —— 在 Windows 10/11 上以托盘程序方式运行,通过 WebSocket 连接 Gotify Server,把新消息以 Windows 原生通知呈现。
## 用户场景
V1 核心场景(用户明确要求):
- Windows 接收 Gotify 通知(WebSocket → Windows 原生通知)
- 应用内查看历史消息(打开 MainWindow → 历史列表,自动拉最近 N 条 + 实时追加新消息)
- 列表条目支持双击跳转:消息 `extras` 里有 `client::notification.click.url` 时,默认浏览器打开
V1 暂不做(避免范围蔓延):多 Gotify Server、消息过滤、GUI 完整配置编辑、MSI/MSIX 安装器、Linux/macOS 端。
## Setup commands
- 环境:Windows 10 19041+ / Windows 11、Visual Studio 2022、.NET 8 SDK、Desktop development with .NET 工作负载
@@ -21,8 +31,9 @@ Windows Gotify Agent —— 在 Windows 10/11 上以托盘程序方式运行,
- `Services/ConfigService.cs` — `config.json` 读写,路径 `%LOCALAPPDATA%\WindowsGotify\config.json`
- `Services/Logger.cs` — 文本日志写入 `app.log`,线程安全
- `Services/StateService.cs` — `state.json` 持久化 `LastMessageId`,断线重连/历史同步的去重锚点
- `Services/GotifyApiService.cs` — `GET /message?limit=&since=` 拉历史消息
- `Services/GotifyWebSocketService.cs` — `/stream?token=...` WebSocket 循环、自动重连(指数退避 2→5→10→20→30→60)、History 补偿
- `Services/GotifyApiService.cs` — `GET /message?limit=&since=` 拉历史补偿;`GetRecentMessagesAsync` 拉最近 N 条(供 UI 历史查看)
- `Services/GotifyWebSocketService.cs` — `/stream?token=...` WebSocket 循环、自动重连(指数退避 2→5→10→20→30→60)、History 补偿;新增 `MessageReceived` 事件供 UI 实时追加
- `Services/NotificationService.cs` — 通过 `AppNotificationBuilder` 弹 Windows 原生通知,Priority ≥ 8 走 Alarm 音;若消息 `extras` 含 `client::notification.click.url`,通过 `AddArgument("url=...")` 透传给 `OnNotificationInvoked`
- `Services/NotificationService.cs` — 通过 `AppNotificationBuilder` 弹 Windows 原生通知,Priority ≥ 8 走 Alarm 音
- `Utils/StartupManager.cs` — 写入 `HKCU\Software\Microsoft\Windows\CurrentVersion\Run` 实现当前用户开机启动
- `Tray/TrayIconService.cs` — WinForms `NotifyIcon` 托盘(打开设置/测试通知/重新连接/退出)