函数实现详解
修改topic的消费者
static Consumer *ModifyConsumer(IUnknown *iUnknown, const Topic *topic, Consumer *oldConsumer, Consumer *newConsumer)
{
if (iUnknown == NULL || topic == NULL || oldConsumer == NULL || newConsumer == NULL) {
return NULL;
}
PubSubImplement *broadcast = GET_OBJECT(iUnknown, PubSubImplement, iUnknown);
if (broadcast->feature == NULL || broadcast->feature->GetRelation == NULL) {
return NULL;
}
Relation *relation = broadcast->feature->GetRelation(broadcast->feature, topic);
if (relation == NULL) {
return NULL;
}
MUTEX_Lock(broadcast->feature->mutex);
ConsumerNode *item = NULL;
UTILS_DL_LIST_FOR_EACH_ENTRY(item, &relation->callbacks.node, ConsumerNode, node) {
if (item->consumer->Equal(item->consumer, oldConsumer)) {
Consumer *older = item->consumer;
item->consumer = newConsumer;
MUTEX_Unlock(broadcast->feature->mutex);
return older;
}
}
MUTEX_Unlock(broadcast->feature->mutex);
return NULL;
}
取消订阅
static Consumer *Unsubscribe(IUnknown *iUnknown, const Topic *topic, const Consumer *consumer)
{
if (iUnknown == NULL || topic == NULL || consumer == NULL) {
return NULL;
}
PubSubImplement *broadcast = GET_OBJECT(iUnknown, PubSubImplement, iUnknown);
if (broadcast->feature == NULL || broadcast->feature->GetRelation == NULL) {
return NULL;
}
Relation *relation = broadcast->feature->GetRelation(broadcast->feature, topic);
if (relation == NULL) {
return NULL;
}
MUTEX_Lock(broadcast->feature->mutex);
ConsumerNode *item = NULL;
UTILS_DL_LIST_FOR_EACH_ENTRY(item, &relation->callbacks.node, ConsumerNode, node) {
if (item->consumer->Equal(item->consumer, consumer)) {
UtilsListDelete(&item->node);
break;
}
}
MUTEX_Unlock(broadcast->feature->mutex);
if (item == &relation->callbacks || item == NULL) {
return NULL;
}
Consumer *oldConsumer = item->consumer;
SAMGR_Free(item);
return oldConsumer;
}
向topic发布数据
static BOOL Publish(IUnknown *iUnknown, const Topic *topic, uint8 *data, int16 len)
{
PubSubImplement *broadcast = GET_OBJECT(iUnknown, PubSubImplement, iUnknown);
PubSubFeature *feature = broadcast->feature;
if (feature == NULL) {
return FALSE;
}
Request request = {MSG_PUBLISH, 0, NULL, *(uint32 *)topic};
if (data != NULL && len > 0) {
request.data = (uint8 *)SAMGR_Malloc(len);
if (request.data == NULL) {
return FALSE;
}
request.len = len;
(void)memcpy_s(request.data, request.len, data, len);
}
if (!ImmediatelyPublish(feature, topic, &request)) {
(void)SAMGR_Free(request.data);
request.data = NULL;
request.len = 0;
return FALSE;
}
return TRUE;
}
DD一下:欢迎大家关注公众号<程序猿百晓生>,可以了解到一下知识点。
1.OpenHarmony开发基础
2.OpenHarmony北向开发环境搭建
3.鸿蒙南向开发环境的搭建
4.鸿蒙生态应用开发白皮书V2.0 & V3.0
5.鸿蒙开发面试真题(含参考答案)
6.TypeScript入门学习手册
7.OpenHarmony 经典面试题(含参考答案)
8.OpenHarmony设备开发入门【最新版】
9.沉浸式剖析OpenHarmony源代码
10.系统定制指南
11.【OpenHarmony】Uboot 驱动加载流程
12.OpenHarmony构建系统--GN与子系统、部件、模块详解
13.ohos开机init启动流程
14.鸿蒙版性能优化指南
.......
向消费者发送数据
/*
函数功能:向消费者发送数据
函数参数:@feature:广播服务子功能对象
@topic:指定的topic
@request:待发送的请求数据
函数返回:发送成功 返回TRUE,发送失败 返回FALSE
函数描述:查询指定topic的订阅关系,获得消费者集合的链表。
遍历消费者结点链表,向订阅了指定topic的所有消费者发送消息。
若消费者绑定了身份标识则调用SAMGR_SendSharedDirectRequest()发送
若消费者未绑定身份标识,则通过SAMGR_SendSharedRequest()发送
*/
static BOOL ImmediatelyPublish(PubSubFeature *feature, const Topic *topic, const Request *request)
{
if (feature->GetRelation == NULL) {
//未初始化,返回FALSE
return FALSE
}
//获取topic的关系
Relation *relation = feature->GetRelation(feature, topic)
if (relation == NULL) {
//关系不存在返回false
return FALSE
}
//判断消费者结点链表是否为空,当链表中只有头结点时,链表判定为空
if (UtilsListEmpty(&relation->callbacks.node)) {
return FALSE
}
//标识消息是否需要异步发送
BOOL needAync = FALSE
ConsumerNode *item = NULL
uint32 *token = NULL
MUTEX_Lock(feature->mutex)
//遍历消费者结点链表,向订阅了指定topic的所有消费者发送消息。
//若消费者绑定了身份标识则调用SAMGR_SendSharedDirectRequest()发送
//若消费者未绑定身份标识,则通过SAMGR_SendSharedRequest()发送
UTILS_DL_LIST_FOR_EACH_ENTRY(item, &relation->callbacks.node, ConsumerNode, node) {
if (item->consumer->identity == NULL) {
//若存在消费者未绑定身份标识,则记录需要异步发送
needAync = TRUE
continue
}
//向绑定了身份标识的消费者直接发送消息
//创建回复消息
Response response = {item->consumer, 0}
//发送调用者的请求和响应。直接调用DefaultHandle来处理请求和响应,而不使用消息处理函数。
int ret = SAMGR_SendSharedDirectRequest(item->consumer->identity, request, &response, &token, DefaultHandle)
if (ret != EC_SUCCESS) {
//发送失败,结束循环
needAync = FALSE
break
}
}
if (needAync) {
//向指定identity发送请求以节省内存。用于为Broadcast服务发布主题,以广播消息。
token = SAMGR_SendSharedRequest(&feature->identity, request, token, NULL)
}
MUTEX_Unlock(feature->mutex)
return (token != NULL)
}
默认的消息处理函数
static void DefaultHandle(const Request *request, const Response *response)
{
Consumer *consumer = (Consumer *)response->data;
if (consumer == NULL || consumer->Notify == NULL || g_pubSubImplement.feature == NULL) {
return;
}
MUTEX_Lock(g_pubSubImplement.feature->mutex);
MUTEX_Unlock(g_pubSubImplement.feature->mutex);
Topic topic = request->msgValue;
consumer->Notify(consumer, &topic, request);
}