文档章节

广播消息模式

NiuYoohoo
 NiuYoohoo
发布于 2017/05/09 18:39
字数 455
阅读 48
收藏 0

接收广播消息的接口,同时又自己能请求广播

class IBroadcastEvent
{
public:
	friend class Broadcaster;
	IBroadcastEvent() :broadcaster(nullptr){}
	virtual void recvMessage(const std::string& msg) = 0;
	virtual void requestBroadcast(const std::string& msg)
	{
		if (broadcaster)
		{
			broadcaster->sendBroadcastMessage(msg);
		}
	}
protected:
	Broadcaster* broadcaster;
};

发送广播对象

//Header
class Broadcaster
{
public:
	Broadcaster(){}
	~Broadcaster(){ recver_list.clear(); }
	void sendBroadcastMessage(const std::string& msg);
	bool operator +=(IBroadcastEvent*);
	bool operator -=(IBroadcastEvent*);
	inline size_t	getCount()const{ return recver_list.size(); }
private:
	std::set<IBroadcastEvent*>		recver_list;
	void detachMsg(IBroadcastEvent*, const std::string& );
	std::mutex protect_mutex;

};
//Source
bool Broadcaster::operator+=(IBroadcastEvent* e)
{

	if (e)
	{
		std::lock_guard<std::mutex> lck(protect_mutex);
		recver_list.insert(e);
		e->broadcaster = this;
		return true;
	}
	return false;
}

 bool Broadcaster::operator-=(IBroadcastEvent* e)
{
	std::lock_guard<std::mutex> lck(protect_mutex);
	recver_list.erase(e);
	e->broadcaster = nullptr;
	return true;
}

 void Broadcaster::sendBroadcastMessage(const std::string& msg)
{
	for (std::set<IBroadcastEvent*>::iterator iter = recver_list.begin(); iter != recver_list.end(); iter++)
	{
		detachMsg(*iter, msg);
	}
}

 void Broadcaster::detachMsg(IBroadcastEvent* e, const std::string& msg)
{
	e->recvMessage(msg);
}

测试

class Listen : public IBroadcastEvent
{
public:
	Listen(std::string name) :instance_name(name){}
	void recvMessage(const std::string& msg)
	{
		cout <<instance_name<<"----->"<< msg << endl;
	}
private:
	std::string instance_name;
};


class Scan : public IBroadcastEvent
{
public:
	void recvMessage(const std::string& msg)
	{
		 cout<<"I'm a scan ,I recv msg:"<< msg << endl;
	}
};
int main()
{
	
	Broadcaster br;

	Listen le0("0");
	Listen le1("1");
	Listen le2("2");
	Listen le3("3");
	br += &le0;
	br += &le1;
	br += &le1;
	br += &le1;
	br += &le2;
	br += &le3;
	int a = 123;
	br.sendBroadcastMessage("hello");
	cout << "==========================================\n";
	br -= &le2;
	string ss = "123456";
	Scan s;
	br += &s;
	br.sendBroadcastMessage("hi");

	s.requestBroadcast("request");

	getchar();
	return 0;
}

结果

  • 3----->hello
    2----->hello
    1----->hello
    0----->hello
    ==========================================
    I'm a scan ,I recv msg:hi
    3----->hi
    1----->hi
    0----->hi
    I'm a scan ,I recv msg:request
    3----->request
    1----->request
    0----->request

注意事项

Broadcaster 和 IBroadcastEvent是相互调用的,并且使用了类成员函数,c++中提供类的前项申明但是不提供类的成员函数申明,所以为了避免矛盾,将两个类分在两个文件中,注意其中一个通过头文件申明,另一个使用前项申明,在实现文件中包含头文件。

举例:

// a.h
#include "b.h"//使用头文件申明

class A
{
public:
	A();
private:
	B b;
};


// a.cpp
#include "a.h"
A::A(){}

// b.h

class A;//类前项申明

class B
{
public:
	void print(A *);
};

//b.cpp
#include "a.h"
#include "b.h"

void B::print(A *a)
{
	;
}

 

© 著作权归作者所有

共有 人打赏支持
上一篇: 简单工厂模式
下一篇: wchar_t* &char* 互转
NiuYoohoo
粉丝 1
博文 49
码字总数 18987
作品 0
赣州
私信 提问
[WCF-Discovery] WCF-Discovery的协议基础:WS-Discovery

我们传统的服务调用的模式都是这样的:客户端在设计时就预先知道目标服务的地址,并基于这个地址创建客户端终结点对服务进行调用。而我们即将介绍的新特性则是你在预先不知道目标服务的地址的...

长平狐
2012/09/04
174
0
Zookeeper的ZAB协议

本文转载自:Zookeeper的ZAB协议 一、ZAB协议 Zookeeper使用了Zookeeper Atomic Broadcast(ZAB,Zookeeper原子消息广播协议)的协议作为其数据一致性的核心算法。ZAB协议是为Zookeeper专门设...

淡淡的倔强
2018/08/27
0
0
Android的framework层音量控制原理分析--hot(key)处理

Android.media.AudioManager中包含了对android.media.AudioService的跨进程AIDL调用封装。 正常处理过程: 1.调整音量是通过AudioManager间接调用AudioService.adjustStreamVolume方法来完成...

鉴客
2011/11/13
2.8K
3
一文详解消息队列的常见功能场景与使用精髓

作者介绍 消息队列(MQ)是一种不同应用程序之间(跨进程)的通信方法。 应用程序通过写入和检索出入列队的数据(消息)来通信,而无需通过专用连接来链接它们。 消息传递指的是程序之间通过...

王新栋
2018/05/14
0
0
ZooKeeper与Paxos

ZooKeeper 没有采用Paxos 协议,采用的是ZAB(ZooKeeper Atomic Broadcast) 是一个典型的分布式数据一致性解决方案 分布式应用可以基于他实现: 数据发布/订阅、负载均衡、命名服务、分布式...

Java搬砖工程师
2018/11/07
0
0

没有更多内容

加载失败,请刷新页面

加载更多

为什么强烈建议大家使用枚举来实现单例

关于单例模式,我的博客中有很多文章介绍过。作为23种设计模式中最为常用的设计模式,单例模式并没有想象的那么简单。因为在设计单例的时候要考虑很多问题,比如线程安全问题、序列化对单例的...

群星纪元
26分钟前
8
0
Confluence 6 超过当前许可证期限进行升级

这个页面将会对你在进行 Confluence 升级的时候超过了当前许可证的期限进行升级的情况。 许可证警告 在升级的过程中,你将会在 Confluence 的应用程序日志(log file)中看到类似下面的错误提...

honeymoose
39分钟前
2
0
顶尖战略咨询公司常用分析模型

1、KANO模型 日本教授狩野纪昭(Noriaki Kano)构建出的kano模型。将影响用户满意度的因素划分为五个类型,包括: 魅力因素:用户意想不到的,如果不提供此需求,用户满意度不会降低,但当提供...

Moks角木
55分钟前
2
0
Linux iptables之mangle表使用案例

mangle表的用途 mangle表的主要功能是根据规则修改数据包的一些标志位,以便其他规则或程序可以利用这种标志对数据包进行过滤或策略路由。 mangel表使用示例 示例1-策略路由1 内网的客户机通...

月下狼
今天
3
0
OSChina 周日乱弹 —— 兼职我想去学学布偶戏

Osc乱弹歌单(2019)请戳(这里) 【今日歌曲】 @clouddyy : 《火炎 - 女王蜂》 《火炎 - 女王蜂》 手机党少年们想听歌,请使劲儿戳(这里) @小鱼丁 :还在睡觉突然接到一个小哥哥电话“x...

小小编辑
今天
223
8

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部