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 文件互传使用了双通道架构

会话sessionIddataType用途建立时间
会话111 (控制通道)传输控制信令、协商17:06:32
会话223 (数据通道)传输实际文件数据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 → BindDeviceConfirmConnect
认证❌ Failed ×2 → ✅ SuccessauthStateChange ×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/451644OnReceiveFileProcess 451644/451644
传输完成OnSendFileFinished IMG_1501837626_000.jpgOnReceiveFileFinished hash ok ✅
媒体入库HandleMediaAsset → ok ✅
断开DisconnectOnSessionClosed_recv
后续🔴 SCREEN_LOCKED → DisableShare failed