yellowcooln/meshcore-health-check
GitHub: yellowcooln/meshcore-health-check
一个自托管Web应用,用于评估MeshCore网络中MQTT观测者的消息覆盖率和可达性。
Stars: 11 | Forks: 3
# Mesh 健康检查
Mesh 健康检查是一个自托管的 Web 应用,用于衡量您的 MQTT 连接观测者网络中的 MeshCore 消息覆盖率。它为用户提供一个短码,等待该代码出现在已配置的 MeshCore 群组频道中,然后根据有多少选定的观测者报告了相同的消息哈希值对结果进行评分。
这个应用的想法来自波士顿的 Nick D。
其他社区健康检查:
- - 英国 Mesh 健康检查



## 功能特性
- 带有有效期和单码使用次数限制的短期可重用测试码
- 逐个观测者接收跟踪,包含路径、RSSI、SNR 和持续时间数据
- 观测者时间线视图,显示每个观测者首次看到消息的时间
- 观测者覆盖地图,支持深色/浅色底图切换
- 可选的基于区域的观测者过滤,使用可配置的 GeoJSON 边界文件和分组层次结构,例如 `新英格兰 -> 马萨诸塞州`
- 可分享的结果链接,由服务器端保留的会话存储支持
- 通过 manifest + service worker 支持可安装的浏览器应用
- 默认观测者目标集加上浏览器端自定义观测者选择
- 通过 [data/observer.json](/home/yellowcooln/mesh-health-check/data/observer.json) 实现的持久化观测者配置文件
- 从 MQTT 学习到的观测者位置会写回 `data/observer.json`
- Cloudflare Turnstile 登陆页面用于机器人防护
- 可选的由环境变量驱动的外部主链接
- Docker 优先部署,位于 Nginx 或 Cloudflare 后面
- CI 中包含 fixture、API 和冒烟测试覆盖
## 工作原理
1. 访问者打开网站,获得一个代码,例如 `MHC-AB12CD`。
2. 用户将该代码发送到配置的 MeshCore 频道。
3. 后端仅监控该频道的 MQTT 观测者数据流。
4. 当匹配的 `GroupText` 消息出现时,应用将所有具有相同消息哈希的接收记录与该代码关联。
5. UI 根据默认观测者集或用户为该代码自定义的选择计算覆盖率。
每个代码:
- 在 `SESSION_TTL_SECONDS` 后过期
- 最多可使用 `MAX_USES_PER_CODE` 次
- 浏览器历史记录保留在当前浏览器会话本地
- 可分享的结果在服务器上保留至 `RESULT_RETENTION_SECONDS`
## 项目布局
- [server.js](/home/yellowcooln/mesh-health-check/server.js): Express 应用,MQTT 数据接收,会话匹配,观测者持久化,Turnstile 验证,WebSocket 更新
- [public/](/home/yellowcooln/mesh-health-check/public): 仪表板,登陆页面,浏览器逻辑,service worker 和样式
- [data/observer.json](/home/yellowcooln/mesh-health-check/data/observer.json): 持久化的观测者公钥配置文件映射,包含 `name`、`lat` 和 `lon`
- [data/session-results.json](/home/yellowcooln/mesh-health-check/data/session-results.json): 用于可分享链接的保留会话结果存储
- [`.env.example`](/home/yellowcooln/mesh-health-check/.env.example): 部署配置模板
- [HOWTO.md](/home/yellowcooln/mesh-health-check/HOWTO.md): 设置和操作员指南
本仓库以容器优先。`docker compose up -d --build` 是预期的运行路径。
## 环境变量
将 [`.env.example`](/home/yellowcooln/mesh-health-check/.env.example) 复制到 [`.env`](/home/yellowcooln/mesh-health-check/.env) 并填入您实际需要的值。
关键分组:
- 应用:`PORT`, `APP_TITLE`, `APP_EYEBROW`, `APP_HEADLINE`, `APP_DESCRIPTION`, `EXTERNAL_LINK_URL`, `EXTERNAL_LINK_LABEL`, `LOG_LEVEL`, `TRUST_PROXY`
- MQTT:`MQTT_HOST`, `MQTT_PORT`, `MQTT_USERNAME`, `MQTT_PASSWORD`, `MQTT_TOPIC`, `MQTT_TRANSPORT`, `MQTT_WS_PATH`, `MQTT_TLS`, `DASH_BROKER_HOST`, 可选 `MQTT_URL`
- 频道:`TEST_CHANNEL_NAME`, `TEST_CHANNEL_SECRET`, 可选 `TEST_CHANNEL_HASH`
- 会话:`SESSION_TTL_SECONDS`, `RESULT_RETENTION_SECONDS`, `MAX_USES_PER_CODE`, `SESSION_RATE_WINDOW_SECONDS`, `SESSION_RATE_MAX`
- 观测者:`OBSERVERS_FILE`, `RESULTS_FILE`, `KNOWN_OBSERVERS`, `OBSERVER_ACTIVE_WINDOW_SECONDS`, `OBSERVER_RETENTION_SECONDS`
- 区域:`REGIONS_FILE`, `REGION_NAME_PROPERTY`, `REGION_GROUP_PROPERTY`
- Turnstile:`TURNSTILE_ENABLED`, `TURNSTILE_SITE_KEY`, `TURNSTILE_SECRET_KEY`, `TURNSTILE_API_URL`, `TURNSTILE_COOKIE_NAME`, `TURNSTILE_TOKEN_TTL_SECONDS`, `TURNSTILE_BOT_BYPASS`, `TURNSTILE_BOT_ALLOWLIST`, `TURNSTILE_VERIFY_RATE_WINDOW_SECONDS`, `TURNSTILE_VERIFY_RATE_MAX`
重要行为:
- 如果设置了 `KNOWN_OBSERVERS`,新代码默认使用该配置的观测者集。
- 如果 `KNOWN_OBSERVERS` 为空,默认目标回退到在配置的时间窗口内活跃的观测者。
- 如果观测者在 `OBSERVER_RETENTION_SECONDS` 内未被接收到,它们将从仪表板目录和地图中移除。
- 设置 `OBSERVER_RETENTION_SECONDS=0` 可禁用过时观测者清理,并保持已知观测者始终可见,无论其存在时间。
- 用户可以在浏览器中为每个新代码覆盖默认目标。
- `data/observer.json` 在启动时加载,并在从 MQTT 元数据学习到新的观测者名称或坐标时更新。
- `data/session-results.json` 为配置的保留窗口保留可分享的结果数据,并在过期后自动清理。
- 仪表板地图仅绘制已保存坐标的观测者。
- 如果设置了 `REGIONS_FILE`,在启动时,已保存坐标的观测者将被分配到区域,并且观测者面板会显示区域过滤按钮。
- `REGION_NAME_PROPERTY` 选择成为可选子区域标签的特征属性。
- `REGION_GROUP_PROPERTY` 选择成为父组标签的特征属性。如果您的 GeoJSON 没有可用的组属性,UI 将回退到平面区域按钮列表。
- `DASH_BROKER_HOST` 仅更改仪表板中显示的 broker 标签。它不会改变实际的 MQTT 连接目标。
- 结果链接使用 `/share/:sessionId`,并在保留的结果过期前保持可用。
- 支持的浏览器可以从仪表板将该站点安装为独立应用。
## 运行应用
```
docker compose up -d --build
```
默认本地 URL:`http://localhost:3090`
如果启用了 Turnstile:
- `/` 提供验证页面
- `/app` 在成功验证后提供仪表板页面
## 安全注意事项
- 将端口 `3090` 限制为仅您的反向代理或内部网络可访问。
- 会话创建和 Turnstile 验证有速率限制。
- 当运行在 Nginx 或 Cloudflare 后面时,请保持 `TRUST_PROXY=1`。
- 应用仅解码配置的测试频道,并忽略同一 MQTT 主题上的所有其他频道流量。
## UI 说明
- 当有哈希可用时,活动会话卡中的消息哈希直接链接到数据包分析器。
- 当启用区域检测时,观测者面板可以定位父区域组或子区域,并且该选择会直接馈入下一个生成的代码的观测者目标集。
- 默认情况下,覆盖地图绘制当前观测者目录。自定义部署可以在页面 `` 上设置 `data-map-observer-scope="expected"` 以仅绘制用于活动会话评分的观测者集。
- 当前会话卡包含一个 `Share` 按钮,用于复制保留的 `/share/:sessionId` 链接。
- 覆盖地图默认使用深色图块,可在 UI 中切换为浅色图块。
- 支持 PWA 安装的浏览器将在仪表板中显示 `Install App` 按钮。
- 页脚始终链接回项目仓库。
- 可选的主链接仅在配置了 `EXTERNAL_LINK_URL` 时出现。
## 解码器说明
应用现在使用 `@michaelhart/meshcore-decoder` 进行运行时 MeshCore 数据包解码。当前的上游包已经处理多字节路径跳跃数据,此仓库应用了一个小型的 postinstall 兼容性补丁,因此发布的 CommonJS 构建在 Node 18 上仍能正常加载。
## 星标历史
标签:CI测试覆盖, Cloudflare保护, GeoJSON边界, MeshCore网络, MITM代理, MQTT监控, 健康检查工具, 地理信息过滤, 数据可视化, 服务工作者应用, 测试代码生成, 消息哈希验证, 消息覆盖率分析, 消息跟踪, 物联网监控, 网络覆盖测量, 自定义脚本, 自托管应用, 覆盖地图, 观察者跟踪, 请求拦截