文章目录

  • 通知中心NotificationCenter
  • 通知队列NotificationQueue
  • 优先级通知队列PriorityNotificationQueue
  • 带时间戳的通知队列TimedNotificationQueue

Poco为模块之间的通信提供了一套事件通知机制,可以实现模块间和线程间的通信。有点类似于QT中的信号和槽机制。通过该机制我们可以在不同的模块单元之间传递自定义数据。通知框架支持两种策略:NotificationCenter(通知中心)和NotificationQueue(通知队列) 。其中通知队列又包含优先级通知队列和带时间戳的通知队列。

通知中心NotificationCenter

通知中心有点像消息订阅的模式。我们通过给通知中心添加观察者(也就是回调函数),来实现消息的订阅。添加了消息观察者之后当我们发送消息的时候,对应的消息观察者就可以收到对应的消息了。有一点需要注意:每个消息观察者绑定的消息类型是固定的,我们可以通过消息类型来实现将特定的消息发送给特定的观察者。对应的调用实现如下:

//自定义消息
class TestNotification: public Notification
{};//通知中心
class NotificationCenterSample
{public:NotificationCenterSample();~NotificationCenterSample();
public:void useNotification();protected:void handle1(Poco::Notification* pNf);void handle2(Poco::Notification* pNf);void handleAuto(const Poco::AutoPtr<Poco::Notification>& pNf);private:std::set<std::string> _set;
};void NotificationCenterSample::handle1(Poco::Notification* pNf)
{poco_check_ptr (pNf);AutoPtr<Notification> nf = pNf;_set.insert("handle1");
}
void NotificationCenterSample::handle2(TestNotification* pNf)
{poco_check_ptr (pNf);AutoPtr<TestNotification> nf = pNf;_set.insert("handleTest");
}
void NotificationCenterSample::handleAuto(const AutoPtr<Notification>& pNf)
{_set.insert("handleAuto");
}void NotificationCenterSample::useNotification()
{//缺省的通知类//NotificationCenter& nc = NotificationCenter::defaultCenter();//通知的观察者NotificationCenter nc;Observer<NotificationCenterSample, Notification> o(*this, &NotificationCenterSample::handle1);//使用自定义的消息Observer<NotificationCenterSample, TestNotification> o2(*this, &NotificationCenterSample::handle2);//对消息参数进行保护nc.addObserver(NObserver<NotificationCenterSample, Notification>(*this, &NotificationCenterSample::handleAuto));//添加消息的观察者nc.addObserver(o);nc.addObserver(o2);//发送通知nc.postNotification(new Notification);//移除观察者nc.removeObserver(Observer<NotificationCenterSample, Notification>(*this, &NotificationCenterSample::handle1));//判断是否包含对应的回调函数//assertTrue (!nc.hasObserver(o));//assertTrue (!nc.hasObservers());//assertTrue (nc.countObservers() == 0);
}

通知队列NotificationQueue

通知队列和通知中心不同,通知队列是一个消息队列。通知队列的两端一端是消息的生产者一端是消息的消费者。生产者负责向消息队列中添加消息,消费者负责读取队列中的消息进行处理。在一些并发性比较高的场景下,我们可以通过引入通知队列,缓解服务端的压力。下面介绍一下通知队列的用法:

//自定义通知
class QTestNotification: public Notification
{public:QTestNotification(const std::string& data): _data(data){}~QTestNotification(){}const std::string& data() const{return _data;}private:std::string _data;
};//使用通知队列
void useQueueDequeue()
{//可以使用缺省的消息队列也可以使用自定义的消息队列。//缺省队列//NotificationQueue& queue = NotificationQueue::defaultQueue();NotificationQueue queue;//队列的长度int queue_size = queue.size();//入队列queue.enqueueNotification(new Notification);//出队列Notification* pNf = queue.dequeueNotification();//释放通知pNf->release();//添加自定义通知queue.enqueueNotification(new QTestNotification("first"));queue.enqueueNotification(new QTestNotification("second"));//添加紧急通知,紧急通知优先级更高queue.enqueueUrgentNotification(new QTestNotification("third"));QTestNotification* pTNf = dynamic_cast<QTestNotification*>(queue.dequeueNotification());pTNf->release();//等待消息来临,可以指定超时时间QTestNotification* pTNf = dynamic_cast<QTestNotification*>(queue.waitDequeueNotification(10));
}//在线程中使用通知队列
class TestClass
{public:void useThreads()protected:void work();private:Poco::NotificationQueue    _queue;std::multiset<std::string> _handled;Poco::FastMutex            _mutex;
};
void TestClass::work()
{Poco::Random rnd;Thread::sleep(50);Notification* pNf = _queue.waitDequeueNotification();while (pNf){pNf->release();_mutex.lock();_handled.insert(Thread::current()->name());_mutex.unlock();Thread::sleep(rnd.next(5));pNf = _queue.waitDequeueNotification();}
}
void TestClass::useThreads()
{const int NOTIFICATION_COUNT = 5000;Thread t1("thread1");Thread t2("thread2");//开辟多个线程,在线程中添加通知RunnableAdapter<TestClass> ra(*this, &TestClass::work);t1.start(ra);t2.start(ra);for (int i = 0; i < NOTIFICATION_COUNT; ++i){_queue.enqueueNotification(new Notification);}while (!_queue.empty()) Thread::sleep(50);Thread::sleep(20);//唤醒所有的等待_queue.wakeUpAll();t1.join();t2.join();t3.join();
}

优先级通知队列PriorityNotificationQueue

普通通知队列的消息顺序是先进先出,后进后出(FIFO),消息队列中消息的顺序跟进入的时间是有关系的。而优先级队列中我们可以给消息指定一个固定的优先级,队列通过优先级的大小来判断消息处理的先后顺序。优先级通知队列的使用方法如下:

//自定义消息
class QTestNotification: public Notification
{public:QTestNotification(const std::string& data): _data(data){}~QTestNotification(){}const std::string& data() const{return _data;}private:std::string _data;
};void usePriorityQueueDequeue()
{//默认优先级队列或自定义优先级队列//PriorityNotificationQueue& queue = PriorityNotificationQueue::defaultQueue();PriorityNotificationQueue queue;//指定消息的优先级queue.enqueueNotification(new Notification, 1);//获得队列的大小int queue_size = queue.size();//出队列Notification* pNf = queue.dequeueNotification();pNf->release();//使用自定义通知queue.enqueueNotification(new QTestNotification("first"), 1);queue.enqueueNotification(new QTestNotification("fourth"), 4);QTestNotification* pTNf = dynamic_cast<QTestNotification*>(queue.dequeueNotification());pTNf->release();//等待通知pTNf = dynamic_cast<QTestNotification*>(queue.waitDequeueNotification(10));
}

带时间戳的通知队列TimedNotificationQueue

带事件戳的消息队列中我们可以自己指定消息的事件戳。消息队列根据消息的时间戳的大小来判定通知的优先级。带时间戳的通知队列的使用方法如下所示:

//自定义消息
class QTestNotification: public Notification
{public:QTestNotification(const std::string& data): _data(data){}~QTestNotification(){}const std::string& data() const{return _data;}private:std::string _data;
};void useTimeDequeue()
{//发送缺省消息TimedNotificationQueue queue;queue.enqueueNotification(new Notification, Timestamp());Notification* pNf = queue.dequeueNotification();pNf->release();//使用自定义通知//为每个通知添加一个时间戳Poco::Clock ts1; ts1 += 100000;Poco::Clock ts2; ts2 += 200000;queue.enqueueNotification(new QTestNotification("first"), ts1);queue.enqueueNotification(new QTestNotification("second"), ts2);QTestNotification* pTNf = 0;while (!pTNf){pTNf = dynamic_cast<QTestNotification*>(queue.dequeueNotification());}pTNf->release();//等待通知,可以指定超时时间QTestNotification* pTNf = dynamic_cast<QTestNotification*>(queue.waitDequeueNotification());}

Poco库使用:事件通知相关推荐

  1. android悬浮窗、收款二维码、相机处理、事件通知库、NFC读取等源码

    Android精选源码 一个漂亮而强大的自定义view SeekBar 适用于Android的简单NFC读取源码 安卓任意界面悬浮窗实现源码 android实现收款二维码保存代码 RxBus 一个简易 ...

  2. Poco库使用:任务管理器TaskManager

    文章目录 1.定义独立任务 2.使用TaskManager启动多个任务 3.TaskManager使用自定义线程池 4.添加任务观察者 5.使用自定义的任务观察者和任务通知 Poco库的任务管理器Ta ...

  3. C++ POCO库(访问数据库,版本问题,本人配置失败)

    官网下载源码:https://pocoproject.org/ 一.POCO库简介 学习一个框架前,要先明白它的是什么,为什么,怎么用.下面这些文字,是从中文poco官网上转过来的,正如poco c+ ...

  4. 基于 C++ POCO 库封装的异步多线程的 CHttpClient 类

    用惯了 Jetty 的 基于事件的 HttpClient 类,在C++平台上也没找到这样调用方式的类库,只好自己写一个了. 目前版本 1.0,朋友们看了给点建议.(注:Kylindai原创,转载请注明 ...

  5. POCO库中文编程参考指南(11)如何使用Reactor框架?

    1 Reactor 框架概述 POCO 中的 Reactor 框架是基于 Reactor 设计模式进行设计的.其中由 Handler 将某 Socket 产生的事件,发送到指定的对象的方法上,作为回调 ...

  6. socket通信之六:Overlapped I/O 事件通知模型实现的客户/服务器模型

    1.基于事件通知模型的Overlapped I/O(重叠IO模型) 概括一点说,重叠模型是让应用程序使用重叠数据结构(WSAOVERLAPPED),一次投递一个或多个Winsock I/O请求.针对这 ...

  7. 基于 WEB 的实时事件通知方式 服务器推送

    下面这些可以实现基于web的实时事件通知的方法.在他们的实验性研究中在一个利用COMET推送方式实现(Dojo的Cometd库,dwr的反向Ajax)的AJAX应用和一个纯拉取方式的应用之间,对数据一 ...

  8. 基于WEB 的实时事件通知方案

    基于WEB 的实时事件通知方案 基于 WEB 的实时事件通知方式大致有五种方案:HTTP拉取方式(pull),HTTP流,Long Polling,FlashXMLSocket方式,Java Appl ...

  9. 基于WEB 的实时事件通知

    基于 WEB 的实时事件通知方式大致有五种方案:HTTP拉取方式(pull),HTTP流,Long Polling,Flash XMLSocket方式,java Applet. 首先说下Comet这个 ...

最新文章

  1. Python中使用数据库SQLite
  2. hadoop分布式集群搭建
  3. 如果遇到Hadoop集群正常,MapReduce作业运行出现错误,如何来查看作业运行日志(图文详解)...
  4. 通过微信企业号发送zabbix报警
  5. 贝叶斯统计:Tweedie公式及其证明
  6. CentOS 初体验五: SSH远程连接
  7. 同步和异步, 阻塞和非阻塞, Reactor和Proactor
  8. Linux中通过命令直接删除文件中最后一行
  9. matplotlib的优点_超详细matplotlib基础介绍!!!
  10. Golang学习 - sync 包
  11. MapBox定位与离线地图下载Android
  12. android多媒体stagefright框架,Android多媒体框架下Stagefright的功能扩展.PDF
  13. web开发框架_Web开发的十大框架
  14. 制作谷歌浏览器 Google Chrome 免安装绿色版!
  15. WindowsCMD配置代理
  16. 多人网络(Valve开发文档翻译[起源引擎])(一)
  17. 联盛德W806-KIT开发板试用评测系列之二:ADC 功能使用与测试
  18. 是否可以同时学习两门编程语言?——我的语言学习经验告诉我不行
  19. 若依专题 线程池配置
  20. JAVA中的Xms、Xmx、MetaspaceSize、MaxMetaspaceSize都是什么意思?

热门文章

  1. Linux 清空文件(6种方式)
  2. canvas将图片转成点阵
  3. Flowable基本使用介绍和Flowable数据库表解释
  4. 小程序 Base64转换字符串
  5. 使用python批量将word转为pdf
  6. 有理谱估计的参数化方法
  7. 什么才是软件定义汽车?
  8. 16个css3动画按钮/纯代码
  9. 【微服务架构】微服务设计模式
  10. 有哪些探测人脑状态的方法 ?