open Harmony文件互传业务流程分析
前言
我这里拿到了文件互传的双端的日志,太长了,就不放出来了,我这里就放我自己分析的
source端(发送端)
文件传输过程详解
17:06:28.695 connectionChange ← 连接状态变更(已连接) 17:06:28.699 SendFile in ← 开始发送文件 17:06:28.701 SendFileStub (cmd:0) ← SA服务端处理发送请求 17:06:28.702 SendManager::SendFile ← 发送管理器启动 17:06:28.703 GetTrustedDeviceList ← 获取可信设备列表 17:06:28.712 GetNetWorkId success ← 获取网络ID成功 17:06:32.624 SyncSendTask sessionId=1 ← 同步发送任务(会话1) 17:06:32.675 OnSessionOpened_send ← 会话1建立成功 (dataType=1, 控制通道) 17:06:32.732 OnMessageReceived_send ← 收到对端响应 (dataLen=7) 17:06:39.015 OpenSessionAndSendFile ← 等待打开文件传输会话 17:06:40.016 waiting 2000ms ← 等待2秒 17:06:41.017 waiting 3000ms ← 等待3秒 17:06:41.748 OnSessionOpened_send ← 会话2建立成功 (dataType=3, 数据通道) 17:06:41.749 OnSending → sendChange ← UI更新:发送中 17:06:43.036 OnSendFileProcess ← 传输进度:451644/451644 ✅ 17:06:43.037 OnSendFileFinished ← 文件发送完成! file = IMG_1501837626_000.jpg 17:06:43.042 SetSendStopFlag ← 设置停止标志 17:06:43.047 Disconnect ← 主动断开连接 17:06:48.164 connectionChange ← 连接已断开双通道传输架构
日志中可以清晰看到 OpenHarmony 文件互传使用了双通道架构:
| 会话 | sessionId | dataType | 用途 | 建立时间 |
|---|---|---|---|---|
| 会话1 | 1 | 1 (控制通道) | 传输控制信令、协商 | 17:06:32 |
| 会话2 | 2 | 3 (数据通道) | 传输实际文件数据 | 17:06:41 |
流程:
控制通道(sessionId=1)建立 → 发送协商消息(dataLen=7) → 等待对端准备 → 数据通道(sessionId=2)建立 → 传输文件完整流程图
用户操作 系统行为 ──────── ──────── GetShareOpenTime 周期查询 ✅ ↓ 用户点击"发送文件" ←─────────── StartScan 扫描设备 ↓ OnDeviceFound ×15+ (发现设备) ✅ ↓ 用户选择目标设备 ←──────────── StopScan ↓ Connect → BindDevice ↓ ❌ Auth Failed (status:8) 超时 ↓ ❌ Auth Failed (status:12) 异常 ↓ (接收端用户确认连接) ←──────── authStateChange ↓ ✅ Auth Success (status:7) ↓ connectionChange (已连接) ↓ 用户选择文件发送 ←──────────── SendFile ↓ 建立控制通道 (sessionId=1, dataType=1) ↓ 发送协商消息 → 收到响应 ↓ 等待1s → 2s → 3s ↓ 建立数据通道 (sessionId=2, dataType=3) ↓ OnSending (传输中...) ↓ OnSendFileProcess 451644/451644 ✅ ↓ OnSendFileFinished IMG_1501837626_000.jpg ✅ ↓ SetSendStopFlag ↓ Disconnect (主动断开) ↓ connectionChange (已断开)Note
中间组网认证失败了两次,那个可能是测试那边没有在对端点确认链接导致超时了,不是错误。
sink端(接收端)
完整时间线
时间 事件 状态 20:03:16 CountdownTimer 开始(578秒) ✅ 20:03:20~04:30 GetShareOpenTime 周期查询(每5秒) ✅ 20:03:32 NAPI 模块加载 + CreateShareManager ✅ 20:03:35 ConfirmConnect 确认连接 ✅ 20:03:53 authStateChange(第1次) 🔄 认证中 20:03:59 authStateChange(第2、3次) 🔄 认证中 20:04:05 connectionChange ×2 ✅ 连接建立 20:04:09 OnSessionOpened_recv sessionId=1, dataType=1 ✅ 控制通道建立 20:04:09 OnMessageReceived_recv 收到文件元信息 ✅ 20:04:09 OnSessionClosed_recv sessionId=1 ✅ 控制通道关闭 20:04:17 OnSessionOpened_recv sessionId=2, dataType=3 ✅ 数据通道建立 20:04:18 OnReceiveFileStarted 开始接收文件 ✅ 20:04:18 OnReceiveFileProcess 451644/451644 ✅ 接收完成 20:04:18 OnReceiveFileFinished hash校验OK ✅ 20:04:19 Handle media asset ok 媒体入库完成 ✅ 20:04:20 OnSessionClosed_recv sessionId=2 ✅ 数据通道关闭 20:04:22 加载 fileshare 模块(图库应用) ✅ 20:04:32 🔴 SCREEN_LOCKED → DisableShare failed ❌ 20:04:32 ChangeUuid ×3 🔄 清理中关键细节:文件接收过程
控制通道---接收文件元信息
20:04:09.636 OnSessionOpened_recv sessionId=1, dataType=1 ← 控制通道建立 20:04:09.687 OnMessageReceived_recv sessionId=1, dataLen=501收到的JSON消息内容
{ "deviceId": "b5cd1e6ebc24849c", "deviceName": "OpenHarmony 3.2", "files": [{ "name": "Screenshot_1501837525983.jpg", "origFileName": "IMG_1501837626_000.jpg", "path": "/mnt/hmdfs/100/account/cloud_merge_view/files/Photo/16/IMG_1501837626_000.jpg", "size": 451644, "uri": "file://media/Photo/1/IMG_1501837626_000/Screenshot_1501837525983.jpg", "utd": "general.jpeg" }], "networkId": "3e3eac6b2808b5670dc1ae04104020bf419a8c25031cd2fae35f71377b8cc7ad", "shareType": 1 }这里可以看到:
- 发送端设备名:OpenHarmony 3.2
- 文件:IMG_1501837626_000.jpg(451,644 字节)
- 文件类型:general.jpeg
- shareType=1 表示单文件分享
存储路径协商
20:04:09.694 ⚠️ GetHapTokenInfo error code: 12100001 20:04:09.694 ⚠️ GetStoragePath preferences failed, return default path 20:04:09.700 storage path = /mnt/hmdfs/100/account/device_view/local/files/Docs/Share前面虽然获取HAP的token信息失败,但是降级处理走default成功了,不影响。
数据通道---文件传输
20:04:17.056 OnSessionOpened_recv sessionId=2, dataType=3 ← 数据通道建立 20:04:17.057 OnSending → sendChange ← UI更新:接收中 20:04:18.794 OnRenameFile → IMG_1501837626_000.jpg ← 文件重命名确认 20:04:18.794 OnReceiveFileStarted sessionId=2 ← 开始接收 20:04:18.796 OnSending → sendChange ← UI更新 20:04:18.866 OnReceiveFileProcess 451644/451644 ← 接收进度100% 20:04:18.867 OnReceiveFileFinished sessionId=2 ← 接收完成 20:04:18.867 Check recv file hash ok ✅ ← Hash校验通过 20:04:19.117 HandleMediaAsset share album id=11 ← 媒体入库 20:04:19.998 Handle media asset ok ✅ ← 入库完成 20:04:20.025 OnSessionClosed_recv sessionId=2 ← 数据通道关闭文件传输耗时极短:从 18.794 到 18.866,仅72ms就完成了 441KB 文件的接收。
屏幕锁定导致disableshare失败
这时候文件传输已经完毕,广播停止了,应该影响不大,后面我问一下。
20:04:32.621 OnReceiveEvent common event=usual.event.SCREEN_LOCKED ← 屏幕锁定 20:04:32.621 DisableShare in ← 尝试关闭共享 20:04:32.621 GetShareStatus (cmd:5) ← 查询当前状态 20:04:32.622 ChangeUuid ← 更新UUID 20:04:32.630 UnPublishDeviceDiscovery ← 取消设备发布 20:04:32.632 StopAdvertising publishId=4082 ← 停止广播 20:04:32.633 ❌ DisableShare failed, ret 96929749 ← 关闭共享失败! 20:04:32.633 ChangeUuid ← 再次更新UUID两端流程对照
| 阶段 | Source(发送端) | Sink(接收端) |
|---|---|---|
| 准备 | GetShareOpenTime 查询 | CountdownTimer 倒计时 + GetShareOpenTime |
| 初始化 | StartScan 扫描 | NAPI加载 + CreateShareManager |
| 发现 | OnDeviceFound ×15+ | — |
| 连接 | Connect → BindDevice | ConfirmConnect |
| 认证 | ❌ Failed ×2 → ✅ Success | authStateChange ×3 |
| 连接建立 | — | connectionChange ×2 |
| 控制通道 | OnSessionOpened_send (id=1, type=1) | OnSessionOpened_recv (id=1, type=1) |
| 文件元信息 | OnMessageReceived_send (dataLen=7) | OnMessageReceived_recv (dataLen=501) |
| 数据通道 | OnSessionOpened_send (id=2, type=3) | OnSessionOpened_recv (id=2, type=3) |
| 文件传输 | OnSendFileProcess 451644/451644 | OnReceiveFileProcess 451644/451644 |
| 传输完成 | OnSendFileFinished IMG_1501837626_000.jpg | OnReceiveFileFinished hash ok ✅ |
| 媒体入库 | — | HandleMediaAsset → ok ✅ |
| 断开 | Disconnect | OnSessionClosed_recv |
| 后续 | — | 🔴 SCREEN_LOCKED → DisableShare failed |