REventBus背景
在實際的項目開發中,經常會遇到業務與業務,組件與組件,業務與組件之間的通信,舉個例子:當有煙霧傳感器檢測到煙霧超標時,需要打開排氣扇排氣,同時顯示煙霧濃度顯示到顯示器中,供管理人員檢視。處理這樣的邏輯有幾種策略。如下:
排氣扇任務和顯示器任務,不斷的查詢煙霧濃度,各自處理檢測煙霧濃度是否超標。
煙霧模塊提供注冊監聽接口,排氣扇任務和顯示器任務分別注冊監聽,當濃度超標時,告知監聽任務。
以上兩種策略都存在很大的問題,問題分析:
第一種策略,每一個任務都需要不斷檢查判斷,這會導致資源的浪費,而且代碼也會有很多重復的。
第二種策略,雖然解決了第一種策略的的問題,但是如果場景中存在不止一個傳感器時,那么所需要注冊的監聽接口將隨之增加。而且監聽接口是跟具體的業務綁定的。
綜上所述:為了能夠解決上面的問題,REventBus組件應運而生。開源鏈接:https://gitee.com/RiceChen0/revent_bus
REventBus工作流程圖解
Publisher使用publish發出ige一個事件,Subscriber在其回調函數中接收事件。
REventBus依賴組件
為了提供更好的組件化,風火輪科技 和《Rice嵌入式開發技術分享》公眾號聯合推出R組件集,REventbus組件就是R組件集的其中一員,組件與組件之后存在依賴關系.REventBus組件同樣依賴一些組件,如下:
RPlatform組件:平臺適配層,為了能讓R組件能夠在不同RTOS或Linux中運行,針對不同平臺做的適配層。鏈接:https://gitee.com/RiceChen0/rplatform。
RThread_pool組件:一個跨平臺,易移植,接口簡單的線程池組件。鏈接:https://gitee.com/RiceChen0/rthread_pool。
REventBus的使用
REventBus整體包含5部分:Subscribe,Publish,Event,EventCb,Broker。
Subscribe --訂閱者訂閱自己需要監聽的事件接口。
Publish --發布者發布事件,它支持同步發送和異步發送。
Event --訂閱者監聽的事件,只有存在訂閱事件,才會有與之對應的發布事件。
EventCb --事件產生的回調接口,訂閱者注冊,發布者發布對應事件之后產生回調。
Broker --事件代理,管理事件注冊,注銷,監聽。
REventBus接口說明
接口 | 說明 |
---|---|
reb_init | REventBus初始化接口 |
reb_deinit | REventBus去初始化接口 |
reb_subscribe | REventBus訂閱事件接口 |
reb_unsbscribe | REventBus取消訂閱事件接口 |
reb_publish | REventBus同步發布事件接口 |
reb_async_publish | REventBus異步發布事件接口 |
REventBus初始化接口
使用RThread_pool組件創建一個線程池
創建互斥量,解決共享資源問題。
初始化broker鏈表,用于事件代理。
pf_err_treb_init(void);
REventBus去初始化接口
線程池注銷,互斥量傷處,
pf_err_treb_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演示
訂閱事件demo:
注意:同一個模塊定義多次定義同一個事件,只有第一個事件訂閱有效
#include#include #include #include"revent_bus.h" voidreb_handler(constchar*event,void*payload,uint16_tlenght) { rt_kprintf("Recv:event:%s,payload:%.*s ",event,lenght,payload); } intmain(void) { reb_init(); reb_subscribe("event1",reb_handler); reb_subscribe("event1",reb_handler); reb_subscribe("event2",reb_handler); reb_info_dump(); }
效果:
發布同步事件demo:
注意:發布同步事件,它是按照順序發布的,只有第一個事件處理完,才會處理第二個事件。
#include#include #include #include"revent_bus.h" voidreb_handler(constchar*event,void*payload,uint16_tlenght) { rt_kprintf("Recv:event:%s,payload:%.*s ",event,lenght,payload); } intmain(void) { rt_kprintf("---------------------- "); rt_kprintf("-Webcometoyouyeetoo- "); rt_kprintf("---------------------- "); 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:eventbus",rt_strlen("youyeetoo:eventbus")); reb_publish("event2","Publishsyncmsg",rt_strlen("Publishsyncmsg")); rt_thread_delay(1000); } }
效果:
發布異步事件demo:
注意:發布異步事件,發布的事件不一定立馬執行,他會等待線程池的任務空閑時,才會執行。也就是執行時間不確定。
#include#include #include #include"revent_bus.h" voidreb_handler(constchar*event,void*payload,uint16_tlenght) { rt_kprintf("Recv:event:%s,payload:%.*s ",event,lenght,payload); } intmain(void) { rt_kprintf("---------------------- "); rt_kprintf("-Webcometoyouyeetoo- "); rt_kprintf("---------------------- "); 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:eventbus",rt_strlen("youyeetoo:eventbus")); reb_publish("event2","Publishsyncmsg",rt_strlen("Publishsyncmsg")); rt_thread_delay(100); reb_async_publish("event1",REB_PRIORITY_ORDINARY,"GoodGood",rt_strlen("GoodGood")); reb_async_publish("event2",REB_PRIORITY_ORDINARY,"Publishasyncmsg",rt_strlen("Publishasyncmsg")); rt_thread_delay(100); } }
效果:
REventBus的優缺點
優點:
簡化組件與組件,業務與業務,組件與業務之間的通信方式。
對通信雙方做到完全解耦。
使用RThread pool靈活切換工作線程,一定程度提供了事件處理效率
支持同步事件發布,和異步事件發布。
資源占用極小。
缺點:
當業務多的時候,需要定義很多事件類型。
訂閱事件的時候,需要遍歷事件列表是否已經存在事件;發布的時候,也需要遍歷事件列表是否已經存在事件,性能不高。
-
顯示器
+關注
關注
21文章
4986瀏覽量
140117 -
接口
+關注
關注
33文章
8639瀏覽量
151385 -
開源
+關注
關注
3文章
3368瀏覽量
42567
原文標題:框架解耦神器 -- REventBus
文章出處:【微信號:風火輪技術團隊,微信公眾號:風火輪技術團隊】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論