一台手机,同时发给平板、PC、笔记本三台设备。其中PC网络慢,会不会把另外两台也拖慢?这就是多设备并发要解决的问题。
前五篇都是"一台设备发给另一台"。
这一篇升级成"一台设备同时发给多台"。
我之前做过一个测试:手机上会议资料,同时发给平板A、平板B、PC。
结果呢?PC网络特别慢,传了半天还没传完。平板A本来10秒就能完成,结果等了30秒。平板B更惨,直接超时失败了。
为什么?因为我把所有设备的任务放在一个队列里跑。PC那个任务卡住了,后面的任务全在等。
这就是多设备并发的坑:一台设备慢,不能影响其他设备。
一、每台设备一个独立Session
正确的做法是:每台目标设备,建一个独立的DeviceSession。
每个Session自己管:
- 自己的任务队列
- 自己的传输状态
- 自己的重试次数
- 自己的统计信息
A设备慢?没关系,它自己慢慢传。B设备正常跑自己的,不受影响。
二、DeviceSession:每台设备独立运行
这段代码解决什么问题:单设备独立会话。
文件:session/DeviceSession.ets
用途:管理单台设备的传输任务
接入位置:多设备分发时创建
classDeviceSession{deviceId:string;deviceName:string;taskQueue:TransferTask[]=[];status:'idle'|'connecting'|'transferring'|'failed'|'completed'='idle';successCount:number=0;failCount:number=0;retryCount:number=0;constructor(deviceId:string,deviceName:string){this.deviceId=deviceId;this.deviceName=deviceName;}// 添加任务addTask(task:TransferTask){this.taskQueue.push(task);}// 处理任务asyncprocessTasks(){this.status='transferring';while(this.taskQueue.length>0){lettask=this.taskQueue.shift()!;try{awaitthis.sendOne(task);this.successCount++;}catch(e){this.failCount++;console.warn('设备 '+this.deviceName+' 任务失败:'+e);}}this.status='completed';}}三、多Session调度:不要互相等
有了多个DeviceSession,怎么调度?
很简单:每个Session独立启动,不要互相等待。
手机同时给三台设备发资料,就是创建三个Session,每个Session独立跑自己的任务队列。
这段代码解决什么问题:多设备并发调度。
文件:scheduler/MultiDeviceScheduler.ets
用途:调度多设备并发传输
接入位置:批量分发时调用
classMultiDeviceScheduler{privatesessions:Map<string,DeviceSession>=newMap();// 创建多设备会话createSessions(devices:Array<{id:string,name:string}>){for(letdevofdevices){letsession=newDeviceSession(dev.id,dev.name);this.sessions.set(dev.id,session);}}// 给所有设备发任务broadcastTask(task:TransferTask){for(letsessionofthis.sessions.values()){// 每个设备一个任务副本lettaskCopy={...task,id:task.id+'_'+session.deviceId};session.addTask(taskCopy);}}// 启动所有会话(并行)asyncstartAll(){letpromises=[];for(letsessionofthis.sessions.values()){promises.push(session.processTasks());}// 等所有完成,不互相阻塞awaitPromise.allSettled(promises);console.info('所有设备传输完成');}}四、多设备并发最容易踩的坑
第一个坑:所有设备共用一个队列。
一台设备慢,整个队列卡住,其他设备都在等。正确做法是每台设备独立队列。
第二个坑:一台失败全部取消。
PC传失败了,平板也跟着取消了。不对,单台失败不影响其他设备。
第三个坑:重复任务没去重。
用户点了两次"全部分发",结果每台设备收到两份相同的任务。要做任务幂等性判断。
第四个坑:内存峰值没控制。
三台设备同时传大文件,每台都读进内存,内存直接涨三倍。要控制每台设备的并发数。
第五个坑:失败重试不隔离。
PC网络不好,一直重试,占着CPU和网络,影响其他设备。重试要限制次数和间隔。
第六个坑:没有性能统计。
哪台设备慢?慢在哪?传了多少?成功率多少?没有统计就是黑盒。
第六篇总结:
多设备并发的核心是"隔离"。每台设备一个独立Session,自己的任务队列、自己的状态、自己的重试。一台设备慢或失败,不影响其他设备。
工程上最容易翻车的是把所有设备的任务放一个队列里,一台卡住全部卡死。分开以后,用Promise.allSettled并行跑,谁慢谁自己等,不拖别人。
下一篇做工程收尾:异常恢复、状态机、资源释放。