鸿蒙实战开发:【分布式软总线组件】

简介

现实中多设备间通信方式多种多样(WIFI、蓝牙等),不同的通信方式使用差异大,导致通信问题多;同时还面临设备间通信链路的融合共享和冲突无法处理等挑战。分布式软总线实现近场设备间统一的分布式通信管理能力,提供不区分链路的设备间发现连接、组网和传输能力,主要功能如下:

  • 发现连接:提供基于Wifi、蓝牙等通信方式的设备发现连接能力。
  • 设备组网:提供统一的设备组网和拓扑管理能力,为数据传输提供已组网设备信息。
  • 数据传输:提供数据传输通道,支持消息、字节、流、文件的数据传输能力。

业务方通过使用分布式软总线提供的API实现设备间的高速通信,不用关心通信细节,进而实现业务平台的高效部署与运行能力。

系统架构


图 1 分布式软总线组件架构图

约束

  • 组网设备需在同一局域网中 或者 距离相近的近场设备间。
  • 组网之前,需先完成设备绑定,绑定流程参见安全子系统中说明。
  • 传输完成数据收发之后,业务要主动关闭会话,释放资源。

说明

使用说明

须知: 使用跨设备通信时,必须添加权限ohos.permission.DISTRIBUTED_DATASYNCohos.permission.DISTRIBUTED_SOFTBUS_CENTER,该权限类型为 dangerous

设备主动发现手机时,手机需打开超级终端的允许被“附近设备”发现开关(设置-超级终端-我的设备-允许被发现-附近设备),才能被设备发现。

1、发现

  • 发布流程
  1. 上层应用需要对外发布自身能力时,调用服务发布接口发布自身能力。

    // 发布回调
    typedef struct {
        /** Callback for publish result */
        void (*OnPublishResult)(int publishId, PublishResult reason);
    } IPublishCb;
    
    // 发布服务
    int32_t PublishLNN(const char *pkgName, const PublishInfo *info, const IPublishCb *cb);
    
  2. 上层应用不再需要对外发布自身能力时,调用StopPublishLNN接口注销服务。

    // 注销服务
    int32_t StopPublishLNN(const char *pkgName, int32_t publishId);
    
  • 发现流程
  1. 上层应用需要发现特定能力设备时,调用发现接口启动发现。

    // 发现回调
    typedef struct {
        /** Callback that is invoked when a device is found */
        void (*OnDeviceFound)(const DeviceInfo *device);
        /** Callback for a subscription result */
        void (*OnDiscoverResult)(int32_t refreshId, RefreshResult reason);
    } IRefreshCallback;
    
    // 发现服务
    int32_t RefreshLNN(const char *pkgName, const SubscribeInfo *info, const IRefreshCallback *cb);
    
  2. 当软总线发现到设备时,通过回调接口通知业务所发现的设备信息。

  3. 上层应用不再需要发现时,调用StopRefreshLNN接口停止设备发现。

    // 停止发现
    int32_t StopRefreshLNN(const char *pkgName, int32_t refreshId);
    

2、组网

  1. 发起组网请求,携带组网连接地址信息,并且提供组网执行结果回调函数。

    // 组网连接地址
    typedef struct {
        ConnectionAddrType type;
        union {
            struct BrAddr {
                char brMac[BT_MAC_LEN];
            } br;
            struct BleAddr {
                char bleMac[BT_MAC_LEN];
                uint8_t udidHash[UDID_HASH_LEN];
            } ble;
            struct IpAddr {
                char ip[IP_STR_MAX_LEN];
                uint16_t port; 
            } ip;
        } info;
        char peerUid[MAX_ACCOUNT_HASH_LEN];
    } ConnectionAddr;
    
    // 组网连接地址类型
    typedef enum {
        CONNECTION_ADDR_WLAN = 0,
        CONNECTION_ADDR_BR,
        CONNECTION_ADDR_BLE,
        CONNECTION_ADDR_ETH,
        CONNECTION_ADDR_MAX
    } ConnectionAddrType;
    
    // 组网请求执行结果回调
    typedef void (*OnJoinLNNResult)(ConnectionAddr *addr, const char *networkId, int32_t retCode);
    
    // 发起组网请求
    int32_t JoinLNN(const char *pkgName, ConnectionAddr *target, OnJoinLNNResult cb);
    
  2. 等待组网结果,JoinLNN()返回成功表示软总线接受了组网请求,组网结果通过回调函数通知业务;组网回调函数中addr参数内容和JoinLNN()的入参互相匹配;retCode如果为0,表示组网成功,此时networkId为有效值,后续传输、退网等接口均需使用该参数;retCode如果不为0,表示组网失败,此时networkId为无效值。

  3. 使用传输相关接口进行数据传输。

  4. 发送退网请求,携带组网成功后返回的networkId,并且提供退网执行结果回调。

    // 退网执行结果回调
    typedef void (*OnLeaveLNNResult)(const char *networkId, int32_t retCode);
    
    // 退网请求
    int32_t LeaveLNN(const char *pkgName, const char *networkId, OnLeaveLNNResult cb);
    
  5. 等待退网完成,OnLeaveLNNResult()的networkId和退网请求接口中的networkId互相匹配;retCode为0表示退网成功,否则退网失败。退网成功后,networkId变为无效值,后续不应该被继续使用。

  6. 使用节点(即设备)注册和注销接口,监听网络中节点状态变化等事件。

    // 事件掩码
    #define EVENT_NODE_STATE_ONLINE 0x1
    #define EVENT_NODE_STATE_OFFLINE 0x02
    #define EVENT_NODE_STATE_INFO_CHANGED 0x04
    #define EVENT_NODE_STATUS_CHANGED 0x08
    #define EVENT_NODE_STATE_MASK 0xF
    
    // 节点信息
    typedef struct {
        char networkId[NETWORK_ID_BUF_LEN];
        char deviceName[DEVICE_NAME_BUF_LEN];
        uint16_t deviceTypeId;
    } NodeBasicInfo;
    
    // 节点状态事件回调
    typedef struct {
        uint32_t events; // 组网事件掩码
        void (*onNodeOnline)(NodeBasicInfo *info);   // 节点上线事件回调
        void (*onNodeOffline)(NodeBasicInfo *info);  // 节点下线事件回调
        void (*onNodeBasicInfoChanged)(NodeBasicInfoType type, NodeBasicInfo *info); // 节点信息变化事件回调
        void (*onNodeStatusChanged)(NodeStatusType type, NodeStatus *status); // 设备运行状态变化事件回调
    } INodeStateCb;
    
    //  注册节点状态事件回调
    int32_t RegNodeDeviceStateCb(const char *pkgName, INodeStateCb *callback);
    
    // 注销节点状态事件回调
    int32_t UnregNodeDeviceStateCb(INodeStateCb *callback);
    

3、传输

  1. 创建Socket。

    typedef struct {
        char *name;                 // 本端Socket名称
        char *peerName;             // 对端Socket名称
        char *peerNetworkId;        // 对端Socket的网络ID
        char *pkgName;              // 调用者包名
        TransDataType dataType;     // 传输的数据类型,需要与发送方法一致
    } SocketInfo;
    
    // 创建Socket
    int32_t Socket(SocketInfo info);
    
  2. 服务端启动监听,客户端进行绑定。

    // Socket回调函数
    typedef struct {
        void (*OnBind)(int32_t socket, PeerSocketInfo info);
        void (*OnShutdown)(int32_t socket, ShutdownReason reason);
        void (*OnBytes)(int32_t socket, const void *data, uint32_t dataLen);
        void (*OnMessage)(int32_t socket, const void *data, uint32_t dataLen);
        void (*OnStream)(int32_t socket, const StreamData *data, const StreamData *ext, const StreamFrameInfo *param);
        void (*OnFile)(int32_t socket, FileEvent *event);
        void (*OnQos)(int32_t socket, QoSEvent eventId, const QosTV *qos, uint32_t qosCount);
    } ISocketListener;
    
    typedef enum {
        QOS_TYPE_MIN_BW,            // 最小带宽
        QOS_TYPE_MAX_LATENCY,       // 最大建链时延
        QOS_TYPE_MIN_LATENCY,       // 最小建链时延
        QOS_TYPE_MAX_WAIT_TIMEOUT,  // 最大超时时间
        QOS_TYPE_MAX_BUFFER,        // 最大缓存
        QOS_TYPE_FIRST_PACKAGE,     // 首包大小
        QOS_TYPE_MAX_IDLE_TIMEOUT,  // 最大空闲时间
        QOS_TYPE_TRANS_RELIABILITY, // 传输可靠性
        QOS_TYPE_BUTT,
    } QosType;
    
    typedef struct {
        QosType qos;
        int32_t value;
    } QosTV;
    
    // 监听Socket,由服务端开启。
    int32_t Listen(int32_t socket, const QosTV qos[], uint32_t qosCount, const ISocketListener *listener);
    
    // 绑定Socket,由客户端开启。
    int32_t Bind(int32_t socket, const QosTV qos[], uint32_t qosCount, const ISocketListener *listener);
    
  3. 通过Socket向对端设备发送数据。

    // 发送字节数据
    int32_t SendBytes(int32_t socket, const void *data, uint32_t len);
    // 发送消息数据
    int32_t SendMessage(int32_t socket, const void *data, uint32_t len);
    // 发送流数据
    int32_t SendStream(int32_t socket, const StreamData *data, const StreamData *ext, const StreamFrameInfo *param);
    // 发送文件
    int32_t SendFile(int32_t socket, const char *sFileList[], const char *dFileList[], uint32_t fileCnt);
    
  4. 关闭Socket。

    // 关闭Socket
    void Shutdown(int32_t socket);
    

    鸿蒙OpenHarmony知识已更新←前往

7ebde29c85a3faa0ae369e2ea9dd3130.jpeg

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/459156.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

鸿蒙开发面试真题分享~

1. 在鸿蒙应用开发中,有哪些常用的性能优化策略和技术手段,如启动速度优化、内存管理优化、功耗控制等? 参考答案: 2. 鸿蒙系统强调跨平台特性,你会如何利用这一特性来优化多端部署和适配? 参考答案&…

Android 音频系统

导入 早期Linux版本采用的是OSS框架,它也是Unix及类Unix系统中广泛使用的一种音频体系。 ALSA是Linux社区为了取代OSS而提出的一种框架,是一个源代码完全开放的系统(遵循GNU GPL和GNU LGPL)。ALSA在Kernel 2.5版本中被正式引入后,OSS就逐步…

力扣111---二叉树的最小深度(简单题,Java,递归+非递归)

目录 题目描述: (递归)代码: (非递归、层次遍历)代码: 题目描述: 给定一个二叉树,找出其最小深度。 最小深度是从根节点到最近叶子节点的最短路径上的节点数量。 说…

鸿蒙Harmony应用开发—ArkTS声明式开发(容器组件:Panel)

可滑动面板,提供一种轻量的内容展示窗口,方便在不同尺寸中切换。 说明: 该组件从API Version 7开始支持。后续版本如有新增内容,则采用上角标单独标记该内容的起始版本。 子组件 可以包含子组件。 说明: 子组件类型&a…

phpcms上传漏洞

原始漏洞 漏洞原理:我们上传一个zip的压缩包,它会解压然后删除其中不是.jpg .gig .png的文件 function check_dir($dir):这是一个PHP函数的定义,它接受一个参数 $dir,代表要检查的目录路径。 $handle opendir($dir)…

抖音电商新店品牌孵化运营打造规划方案

【干货资料持续更新,以防走丢】 抖音电商新店品牌孵化运营打造规划方案 部分资料预览 资料部分是网络整理,仅供学习参考。 PDF共130页(完整资料包含以下内容) 目录 抖音电商运营计划 1. 筹备期 货-人-场匹配 - 确定优质货品…

ANOMALY: meaningless REX prefix used汇总

原因1 未使用指定的python环境 解决方案 使用activate激活指定的python环境 原因2 系统更新然后命令行爆出的错误/电脑中的杀毒软件和系统兼容有问题。 解决方案2 1.将杀毒软件卸载。 2.使用360、电脑管家等对系统进行修复。 原因3 某些软件使用的开源库,比…

苹果Find My App用处多多,产品认准伦茨科技ST17H6x芯片

苹果发布AirTag发布以来,大家都更加注重物品的防丢,苹果的 Find My 就可以查找 iPhone、Mac、AirPods、Apple Watch,如今的Find My已经不单单可以查找苹果的设备,随着第三方设备的加入,将丰富Find My Network的版图。产…

Linux中GPU相关命令

Linux查看显卡信息: lspci | grep -i vga 使用nvidia GPU可以: lspci | grep -i nvidia1 前边的序号 "00:0f.0"是显卡的代号(这里是用的虚拟机); 查看指定显卡的详细信息用以下指令: lspci -v -s 00:0f.01 Linux查看Nvidia显…

电源ATE自动测试系统为您提供一站式自动化测试解决方案

ATECLOUD-POWER电源ATE自动测试系统已为许多客户提供专业的测试解决方案,并且都成功交付。那么电源模块ATE自动测试系统是如何提供测试方案,完成电源测试呢? 在工程师明确用户测试需求、掌握测试方法与步骤之后,从仪器选型到系统开发、再到机…

ACM记忆化DFS与基于优先队列的BFS

基本概念--记忆化DFS 使用数组保存已经算出来的值,在后续的计算中减少大量的重复计算,提高效率。(用于dp不方便,但是搜索方便的情况,可以提升效率。) eg. 记忆化dfs求解斐波那契数列 int dfs(int n) {if…

鱼哥赠书活动第13期:看完这本书教你成为逆向 汇编大佬!!《ARM汇编与逆向工程 蓝狐卷 基础知识》

鱼哥赠书活动第13期:看完这本书教你成为逆向 汇编大佬!! 内容简介:作者简介:译者简介:书本目录:了解更多:赠书抽奖规则:往期赠书福利: 与传统的CISC(Complex …

MWC 2024|「Paraverse平行云」展示空间计算时代沉浸式交互体验

🎉当地时间2月26日,2024年世界移动通信大会(MWC2024)在巴塞罗那拉开帷幕。作为全球移动通信领域最大的技术展会之一,MWC被视为全球通信行业风向标。 🚀随着Vision Pro再次点燃全球空间计算技术热情&#xf…

关于原型的一些总结

猛然发现太久没去复习了,于是复习了一些知识,顺便冒个泡。本次主要总结的知识点关于原型,再文章后半部分有原型相关的题,感兴趣的可直接观看。 一、原型 1.什么是原型 简单理解,原型就是一个对象,通过原…

面试经典150题——随机链表的复制

​前两天断更了两天有点事情🤗 1. 题目描述 2. 题目分析与解析 2.1 思路一 开始还是没什么思路,没思路那就先把题目解决不管方法的好坏。如果不考虑复杂度,该怎么解决? 可以有这样的一种思路: 首先复制链表的所有节…

2024/03/14(网络编程·day2)

一、思维导图 二、TCP通信 //服务器 #include<myhead.h>#define SER_PORT 8888 //服务器端口号 #define SER_IP "192.168.117.103" //服务器IP int main(int argc, const char *argv[]) {//1、创建一个套接字int sfd -1;sfd socket(AF_INET,SOCK_STREAM,…

Uni-app跟学笔记(五):uni-ui组件库的使用、项目打包(小程序、h5、APP)

文章目录 1&#xff09;uni-ui组件库的使用2&#xff09;项目打包1&#xff1a;微信小程序打包2&#xff1a;h5打包3&#xff1a;安卓打包 本博客为 uni-app 此门课的跟学笔记&#xff0c;目的是便于个人复习和对知识快速索引&#xff0c;源码素材可在均可在视频评论区找到 1&a…

Window部署AgileConfig

AgileConfig&#xff1a;分布式配置中心 github&#xff1a;GitHub - dotnetcore/AgileConfig: 基于.NET Core开发的轻量级分布式配置中心 / .NET Core lightweight configuration server 下载部署包&#xff1a;Releases dotnetcore/AgileConfig GitHub 版本&#xff1a;…

LeetCode刷题记录:(9)从中序与后序遍历序列构造二叉树

leetcode传送通道 /*** Definition for a binary tree node.* public class TreeNode {* int val;* TreeNode left;* TreeNode right;* TreeNode() {}* TreeNode(int val) { this.val val; }* TreeNode(int val, TreeNode left, TreeNode right) {* …

HTML5:七天学会基础动画网页11

CSS3动画 CSS3过渡的基本用法: CSS3过渡是元素从一种样式逐渐改变为另一种样式的效果。 过渡属性-transition 值与说明 transition-property 必需&#xff0c;指定CSS属性的name&#xff0c;transition效果即哪个属性发生过渡。 transition-duration 必需&#xff0c;t…