docs: 补 CLAUDE.md 移动端/跨端统计章节 + 新增 urltest 排障文档
ci-pangolin / Lint — shellcheck (push) Has been cancelled
ci-pangolin / OpenAPI Sync Check (push) Has been cancelled
ci-pangolin / Redline Scan — 脱敏 (UI 文案) (push) Has been cancelled
ci-pangolin / Flutter — analyze + test (push) Has been cancelled
ci-pangolin / Portable SQL — 可移植性 (mysql/sqlite) (push) Has been cancelled
ci-pangolin / Codegen Drift — token 生成物未漂移 (push) Has been cancelled
ci-pangolin / Go — build + test (push) Has been cancelled
ci-pangolin / E2E Smoke — L4 进程级端到端 (push) Has been cancelled
ci-pangolin / Go — integration (mysql/redis testcontainers) (push) Has been cancelled
ci-pangolin / Golden — 视觉回归 (components + auth) (push) Has been cancelled

- CLAUDE.md:加「移动端(iOS/iPad+Android)原生隧道」「跨端实时统计+urltest 延迟」两节——
  libbox 构建前置(JDK 17/包名/gitignore)、clash_api 注入正解、libbox 单 client Group 坑、
  Dart 共享广播流、连接态跳直连实测;附「最后在线取 last_seen」一句。
- 新增 docs/connect-latency-urltest.html(排障/Runbook):四端 urltest 实现 + 根因链 + 打点法,
  登记进 docs/index.html。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
wangjia
2026-06-30 22:56:10 +08:00
parent 53fb6492b1
commit e2440e44cc
3 changed files with 129 additions and 0 deletions
+34
View File
@@ -117,3 +117,37 @@ cd web/website && npm run gen:tokens
**已知坑**
- 开发机若是 **macOS 26 (Tahoe)**:`sysextd``no policy, cannot allow apps outside /Applications`(app 在 /Applications 也报)是 **Apple 回归**,本机调试需关 SIP 后 `systemextensionsctl developer on`;真实用户(macOS 14/15)不受影响。
- #5 国内分流:客户端 `smartRoute``?split_cn=1` 下发远程 rule-set;**TODO 改本地 `.srs` 预取**,避免启动期下载。
## client/ 移动端(iOS/iPad + Android)原生隧道
同样内嵌 libbox,与 macOS 同「CommandServer 模型」,但形态/打包不同:
- **iOS/iPad**:`NEPacketTunnelProvider` 扩展(`client/ios/PacketTunnel/`),经 `NETunnelProviderManager` 管理(非 sysext);App Group 用 **iOS 的 `group.` 前缀**(`group.com.pangolin.pangolinVpn`)。`ctl_info`/`sockaddr_ctl` iOS SDK 不发,靠 `PacketTunnel-Bridging-Header.h` 手写声明。
- **Android**:`PangolinVpnService`(`client/android/.../PangolinVpnService.kt`),VpnService + libbox **同进程**;明文联调 API 需 manifest `usesCleartextTraffic`(Android 9+ 默认禁 http)。
- iOS/Android 与 macOS 同走 Dart `VpnNativeBridge`,所以 Dart 侧修复(状态/统计流)四端共享。
**libbox 构建(产物 gitignore,需手动生成)**——`scripts/build-libbox.sh`:
- Apple:`bash scripts/build-libbox.sh apple macos`(只 macOS,快)/ `apple ios`(iOS+sim)→ `Libbox.xcframework``client/{macos,ios}/Frameworks/`
- Android:`bash scripts/build-libbox.sh android``Libbox.aar`,**重命名小写** `libbox.aar``app/kernel/dist/android/`。⚠️ gomobile 编 Android **强制 JDK 17**(JDK 21 直接拒);`export JAVA_HOME=/opt/homebrew/opt/openjdk@17/...` 再编。
- ⚠️ **Android libbox Java 包名是 `io.nekohasekai.libbox`**(不是 `libbox`),Kotlin import 用前者。
## 跨端实时统计 + urltest 延迟(连接页"延迟"的唯一正解)
连接页"延迟"= 内核 urltest(经 REALITY 真实出站测 RTT);**坑很深,改前必读**
`docs/connect-latency-urltest.html`。铁律:
- **服务端下发的 sing-box 配置没有 `clash_api`** → 内核不暴露出站组/urltest 历史 → libbox 的
Group 命令 / `/proxies` 全空。**每个原生端必须在起内核前给配置注入 `experimental.clash_api`
(127.0.0.1 本地监听)+ `cache_file`**,再经本地 HTTP 查 `/proxies`(读 history)+
`/group/<name>/delay`(刷新)取真实延迟(与 Windows desktop bridge 同法)。
- **libbox CommandClient 一连接只订一种命令**:`addCommand(Status)+addCommand(Group)` 同一 client
只第一个生效(Group 永不回调)。速率走 Status,urltest 走上面的 clash HTTP,别指望单 client 的 Group。
- **macOS 扩展是 root、容器与无 root 主 app 不同路径** → 主 app 连不上扩展的 command.sock;macOS/iOS
统计走 `NETunnelProviderSession.sendProviderMessage`(扩展内 StatsCollector 采集、app 拉取)。Android
同进程,直接 socket。
- **Dart 侧**:`VpnNativeBridge.statsStream/statusStream` 必须缓存成**共享广播流**(`asBroadcastStream`)——
否则多订阅者(连接页速度 + ConnectionController 回写延迟)抢 EventChannel 的单一原生 sink,后订阅者赢、
前者变哑(表现:速度正常但延迟一直 —)。`_onStats` 在自动连到已运行隧道(`_connectedNode==null`)时回退
`effectiveNode`;连接态 `_measure` 跳过直连实测(全局 TUN 会本地接住、返回假的几 ms)。
> 设备列表"最后在线"取 `last_seen`(连接/用量/~15s 会话轮询刷新),不是 `last_login`(仅登录那刻)。