当前位置: 首页 > 科技观察

OpenHarmony分布式任务调度源码分析(一)

时间:2023-03-12 03:43:00 科技观察

更多内容请访问:Harmonyos技术社区https://harmonyos.51cto.com前言HarmonyOS支持在本地程序中调用远程任务的功能由一个较低级别的分布式任务调度子系统,并已贡献给开源OpenHarmony代码。为了更全面的了解和掌握分布式任务调度子系统,我将从分布式远程启动这个简单的功能入手,利用鸿蒙的开源代码进行深入学习。下文如无特殊说明,所指的鸿蒙系统均指开源的鸿蒙系统(OpenHarmony3.0LTS版本)。OpenHarmony架构图概述从开源鸿蒙文档入手:分布式任务调度模块,通过主从设备服务代理机制,在OpenHarmony操作系统上建立分布式服务平台,支持主设备(智慧屏设备配备OpenHarmony)启动从设备(IPCamera、运动手表等小内存OpenHarmony设备)FA能力。以智慧屏程序启动提醒为例。在智慧屏的收藏节目菜单中,点击“播后提醒”按钮。程序启动后,智慧屏会在运动手表上拉出程序启动提醒FA。通过这个FA,用户可以快速知道自己喜欢的节目已经启动,达到协同互助的效果。FA:FeatureAbility表示具有与用户交互的界面的Ability。远程启动:即跨设备启动FA,对应本地启动FA。开源鸿蒙系统中的应用按能力分为FA和PA。可以简单的理解为FA就是一个有接口的应用。在分布式服务平台上进行分布式任务调度的前提是设备必须建立分布式服务平台并注册自己的能力。开源的鸿蒙支持三种类型的设备:轻量级、小型和标准。在标配中,开源的鸿蒙已经默认开启了分布式服务平台,开发者一般不需要做额外的工作就可以使用分布式任务调度功能。但是轻小型设备需要在启动代码中实现分布式服务平台的函数调用。详情请参考【分布式软总线子系统】。相关代码库和调用API请参考:【DistributedSoftBus】,【DistributedSoftBuslite】。同一个局域网在上面代码仓库的描述中,反复强调需要保证发现端设备和被发现端设备在同一个局域网内,因为目前开源的鸿蒙系统使用的是coap协议,暂时只支持coap协议。从源码可以看出,以后应该会扩展到BLE、USB等方式。/***@briefEnumeratesmedia,例如蓝牙、Wi-Fi和USB,用于发布服务。**目前,themedia只能设置为coap。**/typedefenum{/**Automaticmediumselection*/AUTO=0,/**Bluetooth*/BLE=1,/**Wi-Fi*/COAP=2,/**USB*/USB=3,}ExchangeMedium;开源的鸿蒙coap协议默认使用的端口是5684,通过udp广播发布在局域网中。如果调试时找不到设备,可以使用该端口进行抓包分析。#defineCOAP_DEFAULT_PORT5684分布式任务调度流程支持开源鸿蒙标准系统的开发板Hi3516D有两款,所以以标准系统的分布式任务调度为例,说明开源鸿蒙系统的分布式任务调度流程。除了开发语言不同外,轻量级系统和小型系统的基本步骤是一样的。开源的鸿蒙系统开发FA目前只支持js/eTS语言。这个demo是指分布式计算器。为了解释方便,做了很多简化,这里忽略错误处理。具体api参考代码仓库:DeviceManager组件。第1步:创建设备管理器importdeviceManagerfrom'@ohos.distributedHardware.deviceManager';letself=this;deviceManager.createDeviceManager("com.example.myapplication",(err,val)=>{self.deviceManager_=val;});在使用DeviceManager相关接口之前,需要通过createDeviceManager接口创建一个DeviceManager实例;第二步:获取可信设备列表vararray=this.deviceManager_.getTrustedDeviceListSync();第三步:注册外围设备动态监控回调函数this.deviceManager_.on('deviceFound',(data)=>{letextraInfo={"targetPkgName":'com.example.myapplication',"appName":'distributedexample'"appDescription":'一个简单的分布式示例',"business":'0'};letauthParam={"authType":1,"appIcon":'',"appThumbnail":'',"extraInfo":extraInfo};self.deviceManager_.authenticateDevice(data.device,authParam,(err)=>{...});});this.deviceManager_.on('deviceStateChange',(data)=>{...});第4步:发现新的周围设备并进行身份验证SUBSCRIBE_ID=Math.floor(65536*Math.random());variinfo={subscribeId:SUBSCRIBE_ID,mode:0xAA,medium:2,freq:2,isSameAccount:false,isWakeRemote:true,capability:0};this.deviceManager_.startDeviceDiscover(info);新设备需要认证才能互联。提供简单的HAP程序,支持弹出PIN码认证机制,使用方便。当前版本仅支持PIN码认证,需提供PIN码认证的授权提示界面、PIN码显示界面、PIN码输入界面;目前由于系统还没有通过native层直接弹出窗口的能力,所以这里临时使用了一个FA来弹出相应的界面。FA为:DeviceManager_UI.hap,预置为系统应用。具体行为是:远程设备在屏幕上显示一个巨大的6位PIN码。控制设备弹出PIN码输入窗口。用户在控制设备上输入遥控设备上显示的PIN码,PIN码输入成功后可以继续遥控,该设备成为可信设备并存储在系统中。下次连接时无需再次验证。第五步:远程调用FA以上步骤1到4是标准的外围设备管理步骤,所以可以打包成函数库供后续使用。用户在获取到信任设备数组后,可以在相应的弹窗或选择界面中选择其中的一个进行连接。findDevices:function(){letself=this;this.remoteDevices.registerDeviceListCallback(()=>{varlist=newArray();vardevs=self.remoteDevices.deviceList;console.info('myapplication:onremotedeviceupdated,count='+devs.length);for(vari=0;i{console.log("myapplication:startabilityfinished:"+JSON.stringify(data));});远程设备收到请求后,会以相应的参数启动相应的FA,启动时可以获取参数:onReady(){featureAbility.getWant((error,want)=>{console.info('myapplication:featureAbility.getWant='+JSON.stringify(want.parameters));//这里isFA就是上面远程请求的参数if(want.parameters.isFA&&want.parameters.isFA==='FA'){this.initKVManager(()=>{console.log('myapplication:kvmanagerstarted.')});}else{this.findDevices();}});},具体API可以参考华为鸿蒙开发文档,注意一些的内容可能与开源的鸿蒙系统不同。请务必编译并运行上述步骤。均已在DevEcoStudio3.0.0.600x64中成功编写,并在两台Hi3516D设备间成功运行。附上代码(分布式远程启动.zip)。如果要在开源的鸿蒙系统上安装HAP程序,首先要在DevEcoStudio中进行签名和相关设置。具体步骤可以参考开源的鸿蒙文档。上传安装HAP程序需要使用开发工具hdc。有关详细信息,请参阅文档。总结开源的鸿蒙系统分布式任务调度的基本功能已经初步完善,使用文档比较分散,需要查阅各个子系统,略显不便。接下来学习分布式软总线和分布式数据,看看开源的鸿蒙系统是如何封装应用间的数据交互能力的。另外看下源码,开源的鸿蒙系统已经具备了分布式应用中转(迁移)的功能,有时间可以学习一下。更多信息请访问:Harmonyos.51cto.com,与华为官方合作打造的鸿蒙技术社区