作为一个曾在会议室传1GB演示视频传到崩溃的开发者,今天要分享HarmonyOS分布式文件传输的实战!当初用断点续传功能救了我差点被毙掉的方案,现在把这些救命技巧全公开~
上周给客户演示方案时,3台设备互传视频差点翻车:
模块 | 职责 | 生活类比 |
---|---|---|
文件发现 | 找设备,像在会议室喊「谁有文件」 | 问同事「PPT发我一下」 |
传输模块 | 传文件,分块送像拆快递分箱 | 大文件拆成小份分批送 |
断点续传 | 记进度,断网后从上次停的地方开始 | 看书折页,下次从折页看起 |
权限控制 | 管钥匙,谁能看谁能改 | 会议室门卡,限权进入 |
import { mdns } from '@kit.NetworkKit';
// 创建设备扫描仪,像会议室点名
let fileScanner = mdns.createDiscoveryService(this.context, '_file_share._tcp');
// 发现设备时记下来
fileScanner.on('serviceFound', (设备) => {
console.log(`找到文件设备:${设备.serviceName},IP:${设备.hostName}`);
// 存到设备列表,方便选传输目标
});
// 开始扫描
fileScanner.startSearchingMDNS();
import { socket } from '@kit.NetworkKit';
// 创建多播通道,像建个文件传送群
let multiSocket = socket.constructMulticastSocketInstance();
let 多播地址 = { address: '239.255.0.1', port: 8888, family: 1 };
// 加入传送群
multiSocket.addMembership(多播地址).then(() => {
console.log('成功加入文件传送群');
// 拆文件成1MB小块
let 文件块 = 拆文件('演示视频.mp4', 1024*1024);
文件块.forEach((块, 编号) => {
// 发送块,带编号方便续传
multiSocket.send({
data: { 编号, 数据: 块 },
address: 多播地址
});
});
});
```
### 3. 断点续传:记「传送进度笔记」
```typescript
// 记每个文件块的进度,像记作业做到哪页
let 传输进度 = new Map();
function 传文件块(文件ID, 块编号, 总块数, 块数据) {
if (块编号 < 总块数) {
// 先查有没有传过
if (!传输进度.get(`${文件ID}-${块编号}`)) {
发送块(文件ID, 块编号, 块数据).then(() => {
// 传成功就记下来
传输进度.set(`${文件ID}-${块编号}`, true);
传文件块(文件ID, 块编号+1, 总块数, 块数据);
}).catch(() => {
console.log(`块${块编号}传丢了,等网好重传`);
// 没传成也记下来,避免重复传
传输进度.set(`${文件ID}-${块编号}`, false);
});
} else {
// 传过的块跳过
传文件块(文件ID, 块编号+1, 总块数, 块数据);
}
}
}
```
## 四、工业级优化:传文件不踩坑
- **多线程加速**:传4K视频时开4个线程同时传,速度提升3倍
- - **动态块大小**:WiFi好时传2MB大块,卡时自动切512KB小块
- - **加密传送**:重要文件用AES加密,像给快递箱上密码锁
## 五、最后碎碎念
现在用这套系统传文件,再也不怕会议室断网了!上次给客户传3GB素材,中途WiFi闪断2次,都自动续传上了~ 但记得第一次调试时,把块编号搞反了,结果文件拼出来是倒的,被同事笑了一周