框架解耦神器 -- REventBus

news2024/11/24 5:09:22

REventBus背景

在实际的项目开发中,经常会遇到业务与业务,组件与组件,业务与组件之间的通信,举个例子:当有烟雾传感器检测到烟雾超标时,需要打开排气扇排气,同时显示烟雾浓度显示到显示器中,供管理人员检视。处理这样的逻辑有几种策略。如下:

  1. 排气扇任务和显示器任务,不断的查询烟雾浓度,各自处理检测烟雾浓度是否超标。
  2. 烟雾模块提供注册监听接口,排气扇任务和显示器任务分别注册监听,当浓度超标时,告知监听任务。

以上两种策略都存在很大的问题,问题分析:

  1. 第一种策略,每一个任务都需要不断检查判断,这会导致资源的浪费,而且代码也会有很多重复的。
  2. 第二种策略,虽然解决了第一种策略的的问题,但是如果场景中存在不止一个传感器时,那么所需要注册的监听接口将随之增加。而且监听接口是跟具体的业务绑定的。

综上所述:为了能够解决上面的问题,REventBus组件应运而生。

REventBus工作流程图解

Publisher使用publish发出ige一个事件,Subscriber在其回调函数中接收事件。

REventBus依赖组件

为了提供更好的组件化,推出R组件集,REventbus组件就是R组件集的其中一员,组件与组件之后存在依赖关系.
REventBus组件同样依赖一些组件,如下:

  1. RPlatform组件:平台适配层,为了能让R组件能够在不同RTOS或Linux中运行,针对不同平台做的适配层。链接:https://gitee.com/RiceChen0/rplatform。
  2. RThread_pool组件: 一个跨平台,易移植,接口简单的线程池组件。链接:https://gitee.com/RiceChen0/rthread_pool。

REventBus的使用

  • REventBus整体包含5部分:Subscribe,Publish,Event,EventCb,Broker。
  • Subscribe --订阅者订阅自己需要监听的事件接口。
  • Publish --发布者发布事件,它支持同步发送和异步发送。
  • Event --订阅者监听的事件,只有存在订阅事件,才会有与之对应的发布事件。
  • EventCb --事件产生的回调接口,订阅者注册,发布者发布对应事件之后产生回调。
  • Broker --事件代理,管理事件注册,注销,监听。
REventBus接口说明
接口说明
reb_initREventBus初始化接口
reb_deinitREventBus去初始化接口
reb_subscribeREventBus订阅事件接口
reb_unsbscribeREventBus取消订阅事件接口
reb_publishREventBus同步发布事件接口
reb_async_publishREventBus异步发布事件接口
  • REventBus初始化接口
  1. 使用RThread_pool组件创建一个线程池
  2. 创建互斥量,解决共享资源问题。
  3. 初始化broker链表,用于事件代理。
pf_err_t reb_init(void);
  • REventBus去初始化接口
  1. 线程池注销,互斥量伤处,
pf_err_t reb_deinit(void);
  • REventBus订阅事件接口: pf_err_t reb_subscribe(const char *event, reb_handler_cb handler)
参数描述
event订阅的事件,其是一个字符串类型
handler事件处理函数,由订阅者提供,事件产生时回调此函数
返回——
PF_EOK订阅事件成功
OTher订阅事件失败
  • REventBus订阅事件接口: pf_err_t reb_unsbscribe(const char *event, reb_handler_cb handler)
参数描述
event订阅的事件,其是一个字符串类型
handler事件处理函数,订阅事件时所订阅的回调函数
返回——
PF_EOK取消订阅事件成功
OTher取消订阅事件失败
  • REventBus同步发布事件接口:pf_err_t reb_publish(const char *event, void *payload, uint16_t lenght)
参数描述
event订阅者订阅的事件类型
payload发布事件的消息类型
lenght发布事件的消息长度
返回——
PF_EOK发布事件成功
OTher发布事件失败
  • REventBus异步发布事件接口:pf_err_t reb_async_publish(const char *event, reb_priority priority, void *payload, uint16_t lenght)
参数描述
event订阅者订阅的事件类型
priority发布事件的优先级,REB_PRIORITY_HIGH和REB_PRIORITY_ORDINARY(目前未实现)
payload发布事件的消息类型
lenght发布事件的消息长度
返回——
PF_EOK发布事件成功
OTher发布事件失败

REventBus演示

  1. 订阅事件demo:
  • 注意: 同一个模块定义多次定义同一个事件,只有第一个事件订阅有效
#include <rtthread.h>
#include <rtdevice.h>
#include <board.h>

#include "revent_bus.h"

void reb_handler(const char *event, void *payload, uint16_t lenght)
{
    rt_kprintf("Recv: event: %s, payload: %.*s\r\n", event, lenght, payload);
}

int main(void)
{
    reb_init();

    reb_subscribe("event1", reb_handler);
    reb_subscribe("event1", reb_handler);
    reb_subscribe("event2", reb_handler);

    reb_info_dump();
}
  • 效果:
  1. 发布同步事件demo:
  • 注意:发布同步事件,它是按照顺序发布的,只有第一个事件处理完,才会处理第二个事件。
#include <rtthread.h>
#include <rtdevice.h>
#include <board.h>

#include "revent_bus.h"

void reb_handler(const char *event, void *payload, uint16_t lenght)
{
    rt_kprintf("Recv: event: %s, payload: %.*s\r\n", event, lenght, payload);
}

int main(void)
{
    rt_kprintf("----------------------\r\n");
    rt_kprintf("-Webcome to youyeetoo-\r\n");
    rt_kprintf("----------------------\r\n");
    reb_init();
	
    reb_subscribe("event1", reb_handler);
    reb_subscribe("event1", reb_handler);
    reb_subscribe("event2", reb_handler);

    reb_info_dump();

    while (1)
    {
        reb_publish("event1", "youyeetoo: event bus", rt_strlen("youyeetoo: event bus"));
        reb_publish("event2", "Publish sync msg", rt_strlen("Publish sync msg"));
        rt_thread_delay(1000);
    }
}
  • 效果:
  1. 发布异步事件demo:
  • 注意:发布异步事件,发布的事件不一定立马执行,他会等待线程池的任务空闲时,才会执行。也就是执行时间不确定。
#include <rtthread.h>
#include <rtdevice.h>
#include <board.h>

#include "revent_bus.h"

void reb_handler(const char *event, void *payload, uint16_t lenght)
{
    rt_kprintf("Recv: event: %s, payload: %.*s\r\n", event, lenght, payload);
}

int main(void)
{
    rt_kprintf("----------------------\r\n");
    rt_kprintf("-Webcome to youyeetoo-\r\n");
    rt_kprintf("----------------------\r\n");
    reb_init();
	
    reb_subscribe("event1", reb_handler);
    reb_subscribe("event1", reb_handler);
    reb_subscribe("event2", reb_handler);

    reb_info_dump();

    while (1)
    {
        reb_publish("event1", "youyeetoo: event bus", rt_strlen("youyeetoo: event bus"));
        reb_publish("event2", "Publish sync msg", rt_strlen("Publish sync msg"));
        rt_thread_delay(100);
        reb_async_publish("event1", REB_PRIORITY_ORDINARY, "Good Good", rt_strlen("Good Good"));
        reb_async_publish("event2", REB_PRIORITY_ORDINARY, "Publish async msg", rt_strlen("Publish async msg"));
        rt_thread_delay(100);
    }
}
  • 效果:

REventBus的优缺点

  • 优点:

    1. 简化组件与组件,业务与业务,组件与业务之间的通信方式。
    2. 对通信双方做到完全解耦。
    3. 使用RThread pool灵活切换工作线程,一定程度提供了事件处理效率
    4. 支持同步事件发布,和异步事件发布。
    5. 资源占用极小。
  • 缺点:

    1. 当业务多的时候,需要定义很多事件类型。
    2. 订阅事件的时候,需要遍历事件列表是否已经存在事件;发布的时候,也需要遍历事件列表是否已经存在事件,性能不高。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

centos7升级rockylinux 未写完

前言 查看centos的版本 &#xff0c;我这台服务器是虚拟机 [rootlocalhost ~]#cat /etc/redhat-release CentOS Linux release 7.9.2009 (Core) [rootlocalhost ~]#uname -a Linux jenkins_server 3.10.0-1160.83.1.el7.x86_64 #1 SMP Wed Jan 25 16:41:43 UTC 2023 x86_64 …

PIC 使能485/422笔记(修订中...)

1.需求 工作中需要把目前设备的单向232转为485/422模式&#xff0c;实现双向通讯&#xff0c;目前查找相关资料。突然想到一件事&#xff0c;我是否能让232现有的单向上发线同时连工控机的tx,rx&#xff0c;然后靠协议&#xff0c;来定时切换PIC一侧的tx rx?PIC可能不支持这个…

Python之pyecharts的常见用法2-柱状图-折线图

Pyecharts是一个基于Echarts的Python可视化库&#xff0c;可以用Python语言轻松地生成各种交互式图表和地图。它支持多种图表类型&#xff0c;包括折线图、柱状图、散点图、饼图、地图等&#xff0c;并且可以通过简单的API调用实现数据可视化。 Pyecharts的优点包括&#xff1a…

关于 Oracle Schema 级别的权限问题

作者 | JiekeXu 来源 |公众号 JiekeXu DBA之路&#xff08;ID: JiekeXu_IT&#xff09; 如需转载请联系授权 | (个人微信 ID&#xff1a;JiekeXu_DBA) 大家好&#xff0c;我是 JiekeXu,很高兴又和大家见面了,今天和大家一起来看看关于 Oracle Schema 级别的权限问题&#xff0c…

PyCaret 3.0介绍 -- Python中的开源、低代码机器学习库

PyCaret是一个Python中的开源、低代码机器学习库&#xff0c;可以自动化机器学习工作流。它是一个端到端的机器学习和模型管理工具&#xff0c;可以成倍地加快实验周期&#xff0c;提高工作效率。 与其他开源机器学习库相比&#xff0c;PyCaret是一个替代的低代码库&#xff0c…

如何利用外卖小程序源码,快速开启你的外卖生意?

作为外卖行业不可或缺的一部分&#xff0c;外卖小程序越来越受到人们的关注。它不仅可以提高用户的订餐体验&#xff0c;还可以为商家带来更高的收益。然而&#xff0c;对于一些想通过外卖小程序来开启自己的外卖生意的商家来说&#xff0c;开发一款定制化的外卖小程序需要投入…

浙江大华后端开发一面面经

目录 1.SpringBuffer和SpringBuilder的区别是什么&#xff1f;2.常用的集合类有哪些&#xff1f;HashMap的底层数据结构&#xff1f;推荐一下线程安全的Map&#xff1f;3.TCP和UDP的差异是什么&#xff1f;4.MySQL的左连接和右连接的区别&#xff1f;5.MySQL慢查询如何排查&…

01 【Vue简介 初识Vue 模板语法和数据绑定】

01 【Vue简介 初识Vue 模板语法和数据绑定】 1.Vue简介 1.1官网 英文官网中文官网 1.2介绍与描述 Vue 是一套用来动态构建用户界面的渐进式JavaScript框架 ○构建用户界面&#xff1a;把数据通过某种办法变成用户界面 ○渐进式&#xff1a;Vue可以自底向上逐层的应用&…

图解LeetCode——108. 将有序数组转换为二叉搜索树

一、题目 给你一个整数数组 nums &#xff0c;其中元素已经按 升序 排列&#xff0c;请你将其转换为一棵 高度平衡 二叉搜索树。 高度平衡 二叉树是一棵满足「每个节点的左右两个子树的高度差的绝对值不超过 1 」的二叉树。 二、示例 2.1> 示例 1&#xff1a; 【输入】n…

企业邮箱大文件发送指南:推荐一个适用于大文件的邮箱服务

大多数电子邮件服务都不安全并且限制附件文件的大小&#xff0c;但是有一些方法可以安全地发送大文件。如果您曾尝试将多个图像或视频文件附加到电子邮件&#xff0c;您就会知道它并不总是有效。下面为大家介绍一款可以发送大文件的企业邮箱--Zoho Mail。 一、电子邮件发送大文…

【Python】Python系列教程--Python3 环境搭建(二)

文章目录 前言Python3 下载Python 安装Unix & Linux 平台安装 Python3:Window 平台安装 Python:MAC 平台安装 Python: 环境变量配置在 Unix/Linux 设置环境变量在 Windows 设置环境变量在命令提示框中(cmd) : 输入 Python 环境变量运行 Python1、交互式解释器&#xff1a;2…

品牌如何给自己创建一个百度百科词条,在百科上传企业资料方法

对于企业来说&#xff0c;很多人都想给自己企业或者品牌上传正面简介内容到百度百科平台&#xff0c;但创建一个品牌百度百科词条似乎并不是那么简答&#xff0c;很多自己尝试创建品牌百度百科词条的朋友最终都失败了&#xff0c;下面洛希爱做百科网教教大家如何给自己品牌创建…

1.矢量引入

目录 一.什么是矢量 1.1 定义 1.2 公理与体系 1.3 矢量几何化 二.矢量间的相互作用 1.点积 2.点积应用 3.叉积 4. 叉积应用 三.矢量除法 1.单用叉积无法唯一定义矢量除法 2.矢量除法 四.复杂相互作用 1.混合积 2.双叉积 3.Laplace公式 五.泛函的广义矢量理论…

从业十三年SEO大佬干货总结,满满五千字,图文结合,30min带你真正学会SEO

目录 seo优化 介绍seo是什么 网站更新&#xff1a; 网站排名在21世纪的意义: 网站为电商引流 百度算法规则 排名流程 seo策略 规则——“学会在线球里玩” 单页面收录显示 必要条件——链接数量 日志统计——及时优化seo策略 降低识别难度 收录越多排名就越大吗 …

B/S电子病历编辑器源码

电子病历编辑器&#xff0c;简称EMRE&#xff08;EMR Editor&#xff09;&#xff0c;是电子病历系统的核心关键基础技术。 B/S电子病历编辑器源码&#xff0c;带演示&#xff0c;自主研发&#xff0c;官方正版授权 ▶本套电子病历系统主要面向医疗机构医生、护士&#xff0c…

【远程办公】外网远程访问公司内网用友畅捷通T财务软件

文章目录 前言1.本地访问简介2. cpolar内网穿透3. 公网远程访问4. 固定公网地址 转发自cpolar极点云的文章&#xff1a;外网远程访问公司内网用友畅捷通T财务软件 – 远程办公 前言 用友畅捷通T适用于异地多组织、多机构对企业财务汇总的管理需求&#xff1b;全面支持企业对远…

微信小程序构建npm(js和ts)

先吐槽一下&#xff0c;官方文档写的就是一坨粑粑&#xff01;真垃圾 微信小程序构建npm js版本下构建npm1.需要在电脑上按照node&#xff0c;并确保环境变量配置完毕2.新建一个小程序项目&#xff0c;js版本3.从小程序根目录打开cmd命令行4.在命令行中执行npm init -y5.继续执…

Linux UIO驱动

目录 什么是UIO&#xff1f; UIO驱动与普通驱动的区别 How UIO works 重要的结构体 UIO驱动源码 APP实现 测试 UIO驱动的优缺点 UIO在DPDK中的使用 什么是UIO&#xff1f; UIO&#xff08;User-space I/O&#xff09;驱动是一种特殊的Linux内核驱动&#xff0c;允许设…

将 PDF 压缩到 1 MB 或更小的 5 个工具

鉴于工作和生活中PDF文件的频繁传输&#xff0c;压缩文件大小成为PDF文件必不可少的一步&#xff0c;尤其是对于包含大量高清图片的文件。压缩不仅使您的文件兼容发送&#xff0c;还有助于存储优化。这意味着您将获得更多数据空间&#xff0c;适用于本地设备和云端。 想要将 …

把控项目进度,这样做就够了

项目管理的核心在于确保项目成员明确项目目标和自己的职责&#xff0c;以此保证项目成功。类比于十字路口中的指路人&#xff0c;项目经理应该为团队提供清晰的方向&#xff0c;避免走错路。 一、项目进度跟踪 项目进度是制胜的关键&#xff0c;它决定了项目是否能够按时达成…