OpenHarmony-分布式软总线发布服务与设备发现
discovery_service.c
前言
分布式软总线是鸿蒙系统的基石,它不仅负责设备间的发现和服务的发布,还要负责实现设备间的数据传输。鸿蒙其他模块,比如设备认证等,都是需要通过软总线来与其他设备进行通信。本篇将基于OpenHarmony(v1.x)对其软总线进行分析。
发布与订阅
概述
分布式软总线实现设备间无感发现,我觉得其一就是这种发布与订阅模式,OpenHarmony系统的服务发布与订阅是基于COAP轻量级协议进行实现的。
主控设备可以提前订阅自己想要的服务,一旦有某个设备发布了这个服务,就可以立刻保存它的设备信息,对应发现端和被发现端的发现逻辑如下:
发现端通过coap广播自己的发现请求,同时被发现端发布自己的服务,当被发现段接收到一个发现请求,那么单播响应该请求。发现端收到响应之后,保存被发现端的设备信息。(OpenHarmony(v1.0.0)dsoft_lite 只具有右边部分,并不具有订阅服务部分,这部分在2.0版 本已经实现)。
服务发布
discovery_service.c实现了轻量级设备端的服务发布功能。
首先介绍服务发布模块的服务结构信息,它包含服务模块的属性:
/* 发布模块结构 publishId : 服务发布ID 标识服务 medium : 服务发布的媒介(wifi 蓝牙..) capabilityBitmap : 对应的功能位图 capabilityData : 服务发布的功能数据 dataLength : 数据长度 */ typedef struct { char package[MAX_PACKAGE_NAME]; int publishId; unsigned short medium; unsigned short capabilityBitmap; char *capabilityData; unsigned short dataLength; unsigned short used; } PublishModule;
首先它的入口函数为 PublishService ,这个函数实现服务发布的总流程。
/* 函数参数: moduleName : 服务模块名 info : 发布的服务信息 IPublishCallback: 服务发布成功或者失败的回调函数 发布成功后会创建会话,等待发现端连接 */ int PublishService(const char *moduleName, const struct PublishInfo *info, const struct IPublishCallback *cb)
在 PublishService 需要做的事主要有:
- 软总线权限和参数检查(目前是查看总线是否开启)
- 初始化功能模块
- 向g_publishModule 添加相应的模块
- 注册服务(将服务数据和功能添加到设备信息中)
- 调用发布服务回调函数
服务发布流程树
发布服务将其他模块紧密结合在一起,理解它的运行流程有助于理清各个模块的关系。下面给出发布服务的流程树(自左往右,自上往下):
一开始对总线权限和参数进行检查,检查完之后就是发布服务初始化,这个初始化分为:初始化基本的设备信息、初始化发布模块和服务数据存储空间、注册回调函数、coap相关初始化、处理IP更新事件、注册设备信息。 这个部分是发布服务中的重中之重,初始化完成之后就将发布info添加到发布模块存储空间,然后注册服务,之后调用发布回调函数。
现在依次分析初始化:
- 初始化基本的设备信息:这一部分很简单,初始化为0,然后初始接口、是否可信账户、设备名、类型、ID、系统版本;
- 初始化发布模块和服务数据存储空间: calloc分配空间;
- 注册wifi事件回调函数(wifiEventTrigger) : 这个函数的触发体现在IP地址事件处理上,它用于获取或清除IP,调用总线管理器开启或关闭软总线、注册设备信息和服务(清空,全部置0)
- coap相关初始化:
-
- CJSON_init 就是使用默认分配和释放函数(malloc/free)。
- 重要的是初始化coap设备发现,这个初始化过程它会创建服务端套接字(g_serverFd)和coap消息ID,并且在创建套接字时,由于当前设备IP为(0.0.0.0),所以内核会随机分配可用IP(INADDR_ANY),然后该套接字绑定该IP(当前还没有存储在设备信息结构体中)。
- 创建一个wifi事件消息队列,这个消息队列存储wifi地址事件的处理信息,并创建一个消息队列监听线程不断的读这个消息队列,一旦有地址事件,那么利用其中的处理函数( wifiEventTrigger )处理。
- 最后,创建coap监听线程监听g_serverFd,调用select等待g_serverFd可读事件发生,因为可读事件发生表示收到了一个发现请求,那么设备就需要进行响应。
5. 处理IP更新事件 : 当前g_serverFd绑定的IP地址,但是IP地址没有存储在设备信息结构体当中,且未开启软总线初始设备信息和服务,所以在coap初始化之后,立即向消息队列中写入一个IP更新事件,然后消息队列监听线程读取出事件信息,创建一个线程调用事件处理函数(wifiEventTrigger),将刚刚绑定的IP存储到设备信息中,然后开启软总线、初始设备信息和服务。
发现请求与响应
服务发布之后,发现设备发现服务,需要对该服务响应请求。
一旦coap监听线程,发现g_serverFd可读了,那么表示收到了一个请求,那么要对请求数据分析,然后来响应这个请求,如图:
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了