原生数据面协议层:桌面 engine 进度节流 / pion 日志 + iOS 数据面路由

- 桌面 engine(pion 数据面,承 ab57afd 之后的精修):
  - 新增 logging.go——把 pion 内部日志路由到宿主 OnLog(真机无 stderr,连接失败无从查);仅 ice/mdns 作用域放 Debug、余 Info+、Trace 丢弃,按 session 聚合
  - wire.go / session.go / engine.go:进度回调 ~10Hz 节流(progressEmitThrottleMs,高吞吐下每片一回调打满宿主主线程;终态由 emitProgressNow 强发最终值),与 web store push 同量级;engine_test.go 跟进
- web 数据面路由:p2p.ts 翻 IOS_NATIVE=true(iOS 走原生 libwebrtc 引擎)+ 新增 p2pIos.ts(iOS p2p 后端)+ p2pNative.ts / net/ios.ts 跟进
- 数据面设计文档 NATIVE-TRANSFER.md:U1(gomobile+pion)真机证伪 → 翻案 U2(libwebrtc)的依据与实测证据(§7/§8)
- 线协议三端一致(cdrop-file ordered / meta+chunk(64KB)+done+ack / 16MB-4MB 水位 / ack 追平完成),桌面 pion ↔ iOS libwebrtc ↔ web JS 互通
This commit is contained in:
2026-06-28 19:32:37 +08:00
parent ab57afdec2
commit f1a00d128e
11 changed files with 587 additions and 22 deletions
+21 -2
View File
@@ -124,9 +124,19 @@ ICE credsGo 拉 /api/calls/credentials(带 a.token),与 JS 同源
---
## 7. iOS 数据面:经 gomobile 与桌面共用同一份 Go 引擎U1POC
## 7. iOS 数据面:libwebrtcU2POC 翻案后定
**决策(2026-06-27,研究后翻案)**:iOS 不再「维持现状 + 仅靠 striping」,而是**把数据面也迁到 Go/pion,经 `gomobile bind` 与桌面共用同一份引擎**——原生侧只一份实现(web 仍 JS,共 2 份引擎),iOS 彻底摆脱 WebKit 256KB。依据用户方针「多端统一 + 各情况性能」,且桌面已定 pion——iOS 同走 pion 即与桌面**同引擎、同特性、同协议**,统一性最大。**该决策以一个 2 天 POC 为闸**(见 §8 Phase 2
> **⚠️ 决策反转(2026-06-28,真机 POC 证伪 U1**:下方 U1gomobile+pion)方案在真机 POC 阶段**撞上架构性硬阻塞、已废弃**,按 §8 Phase 2 闸“撞硬阻塞→退 U2”转用 **libwebrtc.framework**
>
> 实测证据:iOS 经 gomobile/pion 时 Go 的 raw BSD socket 不与 iOS Network framework 集成(WebKit/libwebrtc 才集成)——Mac→iOS 常连不上(~30s ICE 超时)、iOS→Mac 偶连上 host↔host 但 ~4.5MB 中途断流(`read/write on closed pipe`)、TURN CreatePermission 刷屏、时好时坏。接口 / 链路本地 / IPv4-only 过滤只去噪、治不了架构不兼容(且那些 iOS 定向过滤漏进桌面共享引擎致 IPv6 host 对被裁退中继、重大回归)。即下方 §137 标注的“LOW-MEDIUM 成熟度、无 pion+gomobile 生产先例”风险兑现。
>
> **U2 落地(现行)**:JS 路由 / 桥协议 / 线协议 / `IOS_NATIVE` 开关全不变,只把 Swift 侧原生引擎从 gomobile `EngineEngine` 换成 `ios/CDrop/Sources/Engine/LibWebRtcEngine.swift`libwebrtc `RTCPeerConnection`stasel/WebRTC M149 经 SPM、pin 精确版本 149.0.0)。该引擎是 `engine.go`/`session.go` 线协议的忠实 Swift 端口——DataChannel `cdrop-file`ordered)、meta/分片(64KB)/done/ack 文本+二进制帧、16MB/4MB 水位背压、ack 追平完成、不冲突落盘,逐字节对齐桌面 pion 与 web JS 引擎,故 iOS↔桌面、iOS↔浏览器互通。桌面数据面仍走 pion(isDesktop 分支,不受影响)。libwebrtc 与 iOS 网络栈原生集成 + DcSCTP 默认 ~5MB rwnd(不受 WebKit 256KB 限),是吞吐与连通性的根治。
>
> **验证(2026-06-28**:模拟器全 app(含 Share/控件扩展)编译过 + web typecheck/build 过;**环回端到端测试**(两个 LibWebRtcEngine 同进程交叉连、20MB 文件经完整线协议传输后逐字节完整性比对)✅ 过(`ios/CDrop/Tests/LibWebRtcEngineTests.swift``just ios-sim-build` 同款免签名构建)。真机 / 真网吞吐为剩余闸(须 deploy prod 让设备拿到 `IOS_NATIVE=true` 的引擎 + 真机装机,二者 Touch ID 门控)。
>
> 以下 U1 分析保留作历史依据(解释为何最终落 U2、以及 U2 的对照评估)。
**(历史·已废弃)决策(2026-06-27,研究后翻案)**:iOS 不再「维持现状 + 仅靠 striping」,而是**把数据面也迁到 Go/pion,经 `gomobile bind` 与桌面共用同一份引擎**——原生侧只一份实现(web 仍 JS,共 2 份引擎),iOS 彻底摆脱 WebKit 256KB。依据用户方针「多端统一 + 各情况性能」,且桌面已定 pion——iOS 同走 pion 即与桌面**同引擎、同特性、同协议**,统一性最大。**该决策以一个 2 天 POC 为闸**(见 §8 Phase 2)。
**研究结论(U1 = gomobile + pion):**
- **可行,但不直接 bind pion**pion 公开 API 含 gobind 不支持的类型,pion#1111)。正解=写一层 gobind-clean 的 `engine` 薄包装内部引 pion,再 `gomobile bind ./engine``.xcframework`。pion 维护者本人推荐 gomobilediscussion#1746)。
@@ -167,6 +177,15 @@ ICE credsGo 拉 /api/calls/credentials(带 a.token),与 JS 同源
| **Phase 1(落地 A·桌面)** | Go `p2pengine`pion,单关联)+ `p2pBackend` 抽象 + 桥接 + 原生取文件路径;relay/编排留 JS | 桌面↔桌面/Chrome/iOS-LAN **双向快**;隐藏窗口传输满速;去 base64 桥;mac 落 host↔host |
| **Phase 2iOS POC 闸,~2 天)** | 最小 `engine` 包装 → `gomobile bind -target ios`(用最新 `golang.org/x/mobile`)→ Swift 调 `StartOutgoing` | ① 编译出 xcframework;② iOS 上 Go 开 UDP 拿到 **host 候选** + 本地网络权限弹窗;③ 真跑 `iOS(pion)↔桌面(pion)``iOS(pion)↔浏览器` 传输达预期。**过→锁 U1;撞硬阻塞→退 U2** |
| **Phase 3(落地 U1·iOS** | iOS 数据面接入共享 Go 引擎(gomobile xcframework + iOS 侧 `p2pBackend` binding);JS 编排/hub/presence 留 WKWebView | iOS 摆脱 256KBiOS↔* 高 RTT 大幅改善;与桌面**同引擎** |
> **进度(2026-06-28):Phase 2 POC 证伪 U1 → 转 U2libwebrtc);Phase 3U2 版)✅ 代码完成、模拟器编译 + 环回端到端测试绿,待真机/真网吞吐验。**
> - **Phase 2 闸结果=撞硬阻塞、退 U2**gomobile bind 出 `CdropEngine.xcframework` 编译过(①),但真机 ②③ 失败——Go raw socket 不与 iOS Network framework 集成,连接时好时坏 + 中途断流(详见 §7 反转 banner 实测证据)。按闸“撞硬阻塞→退 U2”转 libwebrtc。U1 集成(gomobile 桥)已整体移除。
> - **U2 集成已落地**JS 桥 / 协议 / `IOS_NATIVE` 开关不变,仅换 Swift 引擎;桥协议本就引擎无关):
> - Swift`ios/CDrop/Sources/Engine/LibWebRtcEngine.swift``LibWebRtcEngine` + `P2PTransferSession`libwebrtc RTCPeerConnection,端口 `engine.go`/`session.go` 线协议 + 水位背压 + ack 完成 + 不冲突落盘);`NativeTransfer.swift` 的 `P2PEventsBridge` 改 conform `P2PEngineDelegate`(去 gomobile `import CdropEngine`,事件名 / payload 形状不变);`EngineController` 4 个 p2p RPC 改调新引擎(completion-based,经 `resolveOnMain` 跳主线程 resolve;去 gomobile `EngineEngine` / `runEngine` / `engineQueue`——libwebrtc 自管线程)。
> - 构建:`project.yml` 去 `Frameworks/CdropEngine.xcframework`、接 SPM `WebRTC``exactVersion 149.0.0`+ 加 `CDropTests` 测试 target`Justfile` 去 `ios-engine` recipegomobile bind)、加 `ios-sim-build`(模拟器免签名自检)、`ios-device` 去 chain 的 `ios-engine`。
> - JS`p2p.ts` 的 `IOS_NATIVE` 翻 `true``p2pIos.ts` / `net/ios.ts` 一字不改)。
> - **测试**`ios/CDrop/Tests/LibWebRtcEngineTests.swift` 环回端到端(两个引擎同进程交叉连,20MB 逐字节完整性)✅;模拟器全 app 编译 ✅;web typecheck + build ✅。
> - **真机测试前提**(同 U1):iOS 加载 `engine.html` 自 prod,故须让设备拿到含 `IOS_NATIVE=true` 的引擎——deploy prodgated,浏览器/桌面零影响)或 `CDROP_ENGINE_URL` 指本地安全源(见 REALDEVICE §C);真机装机走 `just ios-device <udid>`(首次自动经 SPM 拉 `WebRTC.xcframework`,无 gomobile 预构建步骤)。
| **Phase 4(按需)** | 共享协议 **N 关联 striping**JS 引擎 for webGo 引擎 for 桌面+iOS | 解跨 NAT 高 RTT 残差(全端) |
---