往期知识点记录:
- 鸿蒙(HarmonyOS)应用层开发(北向)知识点汇总
- OpenHarmony轻量系统服务管理-samgr主要接口思维导图(1)
- OpenHarmony轻量系统服务管理-samgr主要接口思维导图(2)
- OpenHarmony轻量系统服务管理-samgr:common赏析及实现
- OpenHarmony轻量系统服务管理-samgr:iunknown赏析
- OpenHarmony轻量系统服务管理-samgr:iunknown实现分析
- OpenHarmony轻量系统服务管理samgr-message赏析
- OpenHarmony轻量系统服务管理samgr-message实现分析(1)
- OpenHarmony轻量系统服务管理samgr-message实现分析(2)
- OpenHarmony轻量系统服务管理samgr-service赏析
- OpenHarmony轻量系统服务管理samgr-samgr_lite赏析
- OpenHarmony轻量系统服务管理samgr-feature赏析及实现
- OpenHarmony轻量系统服务管理samgr-service实现分析(1)
- OpenHarmony轻量系统服务管理samgr-service实现分析(2)
- OpenHarmony轻量系统服务管理samgr-task_manager赏析及实现(1)
- OpenHarmony轻量系统服务管理samgr-task_manager赏析及实现(2)
- OpenHarmony轻量系统服务管理|samgr_lite功能详解(一)
- OpenHarmony轻量系统服务管理|samgr_lite功能详解(二)
- OpenHarmony轻量系统服务管理|samgr_lite功能详解(三)
- OpenHarmony轻量系统服务管理|samgr_lite功能详解(四)
- OpenHarmony轻量系统服务管理|samgr_client功能详解
- 持续更新中……
一、前言
在samgr_client
部分,当前的代码版本中只提供了一些用于服务远程注册和发现的函数方法。相关实现代码在distributedschedule_samgr_lite\samgr_client\source\remote_register.c
。
二、宏定义及数据结构
#define RETRY_INTERVAL 2 //重试时间间隔
#define MAX_RETRY_TIMES 10 //最大重试次数
#define ABILITY_UID_START 100 //起始的UID
static RemoteRegister g_remoteRegister; //全局注册信息
static BOOL g_isAbilityInited = FALSE; //标识Ability是否已被初始化
struct RemoteRegister {
MutexId mtx; //锁
Endpoint *endpoint; //当前进程的通信端点
Vector clients; //代理接口的集合,存储的是IUnknown类型数据
};
struct RemoteRegister {
MutexId mtx; //锁
Endpoint *endpoint; //当前进程的通信端点
Vector clients; //代理接口的集合,存储的是IUnknown类型数据
};
三、函数实现详解
注册服务和功能
/*
函数功能:向endpoint注册服务和功能
函数参数:@service:服务名称
@feature:功能名称
@identity:服务和功能的身份标识
@iUnknown:注册的接口
函数描述:将指定的服务和功能注册到endpoint中,并向主endpoint发送请求,配置和获取服务和功能的访问地址和访问策略
*/
int SAMGR_RegisterServiceApi(const char *service, const char *feature, const Identity *identity, IUnknown *iUnknown)
{
if (service == NULL) {
return EC_INVALID;
}
//判断g_remoteRegister是否初始化,若未初始化,则进行初始化操作
InitializeRegistry();
//加锁
MUTEX_Lock(g_remoteRegister.mtx);
//设置服务和特性的标识
SaName saName = {service, feature};
//封装成router,添加到全局变量g_remoteRegister.endpoint的routers中
//router在routers中的索引作为token。SAMGR_AddRouter()会触发注册操作
int32 token = SAMGR_AddRouter(g_remoteRegister.endpoint, &saName, identity, iUnknown);
MUTEX_Unlock(g_remoteRegister.mtx);
if (token < 0 || !g_remoteRegister.endpoint->running) {
//token无效或者endpoint启用失败
return token;
}
//为saName指定的service和feature配置policy
return SAMGR_ProcPolicy(g_remoteRegister.endpoint, &saName, token);
}
发现服务接口
/*
函数功能:查找服务代理接口
函数参数:@service:服务名称
@feature:功能名称
函数返回:成功 返回代理接口,失败 返回NULL
函数描述:根据服务名称和功能名称查找指定的代理接口。
若g_remoteRegister.clients中存在该代理接口,则返回它。
若不存在,则创建对应的代理接口并添加到clients中,最后返回它。
*/
IUnknown *SAMGR_FindServiceApi(const char *service, const char *feature)
{
if (service == NULL) {
return NULL;
}
//判断g_remoteRegister是否初始化,若未初始化,则进行初始化操作
InitializeRegistry();
//设置服务和特性的标识
SaName key = {service, feature};
//根据键值查询,返回指定元素的下标
int index = VECTOR_FindByKey(&g_remoteRegister.clients, &key);
if (index != INVALID_INDEX) {
//指定的对象已存在,直接返回它
return VECTOR_At(&g_remoteRegister.clients, index);
}
//代理不存在,则新建
//创建IPC代理
IUnknown *proxy = SAMGR_CreateIProxy(g_remoteRegister.endpoint->context, service, feature);
if (proxy == NULL) {
return NULL;
}
//加锁,保证互斥
MUTEX_Lock(g_remoteRegister.mtx);
//根据键值查询,返回指定元素的下标
index = VECTOR_FindByKey(&g_remoteRegister.clients, &key);
if (index != INVALID_INDEX) {
//代理已存在
MUTEX_Unlock(g_remoteRegister.mtx);
//释放对IUnknown接口的引用
proxy->Release(proxy);
//指定的对象已存在,直接返回它
return VECTOR_At(&g_remoteRegister.clients, index);
}
//代理不存在,则将proxy添加到clients中
VECTOR_Add(&g_remoteRegister.clients, proxy);
MUTEX_Unlock(g_remoteRegister.mtx);
//记录创建代理的日志
HILOG_INFO(HILOG_MODULE_SAMGR, "Create remote sa proxy[%p]<%s, %s>!",
proxy, service, feature);
return proxy;
}
注册syscap
//注册syscap
int32 SAMGR_RegisterSystemCapabilityApi(const char *sysCap, BOOL isReg)
{
//判断g_remoteRegister是否初始化,若未初始化,则进行初始化操作
InitializeRegistry();
//添加syscap,向主endpoint发送包含syscap的消息
return SAMGR_AddSysCap(g_remoteRegister.endpoint, sysCap, isReg);
}
查询syscap注册状态
//查询syscap的注册状态
BOOL SAMGR_QuerySystemCapabilityApi(const char *sysCap)
{
//判断g_remoteRegister是否初始化,若未初始化,则进行初始化操作
InitializeRegistry();
//初始注册状态值为false
BOOL isReg = FALSE;
//查询syscap的注册状态,将结果存在isReg中
if (SAMGR_GetSysCap(g_remoteRegister.endpoint, sysCap, &isReg) != EC_SUCCESS) {
//查询失败则返回false
return FALSE;
}
//查询成功,则返回实际isReg值
return isReg;
}
查询所有已注册的syscap
//获取所有已注册的syscap的数目存储在size中,并将所有的syscap的name存在sysCaps中
int32 SAMGR_GetSystemCapabilitiesApi(char sysCaps[MAX_SYSCAP_NUM][MAX_SYSCAP_NAME_LEN], int32 *size)
{
//判断g_remoteRegister是否初始化,若未初始化,则进行初始化操作
InitializeRegistry();
//向主endpoint查询所有的syscap
return SAMGR_GetSystemCapabilities(g_remoteRegister.endpoint, sysCaps, size);
}
清除注册信息
//清空g_remoteRegister的信息,回收资源
static void ClearRegistry(void)
{
if (g_remoteRegister.endpoint == NULL) {
//g_remoteRegister未初始化,不需要释放资源,直接返回
return;
}
//g_remoteRegister中有数据,需要清空并回收
//记录日志
HILOG_INFO(HILOG_MODULE_SAMGR, "Clear Client Registry!");
//释放锁资源
SAMGR_Free(g_remoteRegister.mtx);
g_remoteRegister.mtx = NULL;
//清空clients的内容
VECTOR_Clear(&(g_remoteRegister.clients));
//清空routers的内容
VECTOR_Clear(&(g_remoteRegister.endpoint->routers));
//关闭当前进程的IPC通道
CloseLiteIpc(g_remoteRegister.endpoint->context);
//回收资源
SAMGR_Free(g_remoteRegister.endpoint);
g_remoteRegister.endpoint = NULL;
}
初始化g_remoteRegister对象
/*
函数功能:初始化g_remoteRegister对象
函数描述:判断g_remoteRegister是否被初始化,若未初始化则清空内部数据,进行初始化操作。若已被初始化则返回。
*/
static void InitializeRegistry(void)
{
//getuid()用来取得执行目前进程的用户id
if (getuid() >= ABILITY_UID_START && !g_isAbilityInited) {
//若getuid的值合法并且Ability未被初始化
//清空已有信息,回收资源,防止g_remoteRegister未初始化但内部有数据
ClearRegistry();
//标记为已初始化,进入初始化操作
g_isAbilityInited = TRUE;
}
//g_isAbilityInited标记为TRUE,判断g_remoteRegister是否有数据
if (g_remoteRegister.endpoint != NULL) {
//g_remoteRegister已被初始化,则返回
return;
}
//开始对g_remoteRegister初始化
HILOG_INFO(HILOG_MODULE_SAMGR, "Initialize Client Registry!");
//给g_mutex加锁
MUTEX_GlobalLock();
if (g_remoteRegister.endpoint == NULL) {
//初始化锁
g_remoteRegister.mtx = MUTEX_InitValue();
//创建vector,以SAMGR_GetSAName作为获取key值的函数,以SAMGR_CompareSAName作为key的比较函数
g_remoteRegister.clients = VECTOR_Make((VECTOR_Key)SAMGR_GetSAName, (VECTOR_Compare)SAMGR_CompareSAName);
//创建endpoint并初始化,endpoint的name为ipc client,通信端点的注册函数为RegisterRemoteEndpoint,向主endpoint注册自己的地址
g_remoteRegister.endpoint = SAMGR_CreateEndpoint("ipc client", NULL);
}
MUTEX_GlobalUnlock();
}
写在最后
如果你觉得这篇内容对你还蛮有帮助,我想邀请你帮我三个小忙:
- 点赞,转发,有你们的 『点赞和评论』,才是我创造的动力。
- 关注小编,同时可以期待后续文章ing🚀,不定期分享原创知识。
- 想要获取更多完整鸿蒙最新学习资源,请看下图提示: