NetMQ 发布订阅模式 Publisher-Subscriber
第一部分引用于:点击打开
1:简单介绍
PUB-SUB模式一般处理的都不是系统的关键数据。发布者不关注订阅者是否收到发布的消息,订阅者也不知道自己是否收到了发布者发出的所有消息。你也不知道订阅者何时开始收到消息。类似于广播,收音机。因此逻辑上,它都不是可靠的。这个可以通过与请求响应模型组合来解决。

图1:简单的发布订阅模式

图2:与请求响应模式组合的发布订阅模式
2:案例
定义IPublishser接口
namespace NetMQDemoPublisher
{
public interface IPublisher:IDisposable
{
/// <summary>
/// 发布消息
/// </summary>
/// <param name="topicName">主题</param>
/// <param name="data">内容</param>
void Publish(string topicName, string data);
}
}
Publisher实现类
namespace NetMQDemoPublisher
{
public class Publisher:IPublisher
{
private object _lockObject = new object(); private PublisherSocket _publisherSocket; public Publisher(string endPoint)
{
_publisherSocket = new PublisherSocket();
_publisherSocket.Options.SendHighWatermark = ;
_publisherSocket.Bind(endPoint);
}
#region Implementation of IDisposable /// <summary>
/// 执行与释放或重置非托管资源相关的应用程序定义的任务。
/// </summary>
public void Dispose()
{
lock (_lockObject)
{
_publisherSocket.Close();
_publisherSocket.Dispose();
}
} /// <summary>
/// 发布消息
/// </summary>
/// <param name="topicName">主题</param>
/// <param name="data">内容</param>
public void Publish(string topicName, string data)
{
lock (_lockObject)
{
_publisherSocket.SendMoreFrame(topicName).SendFrame(data);
}
} #endregion
}
}
Publisher窗口界面

界面中实现的功能代码
namespace NetMQDemoPublisher
{
public partial class PublisherForm : Form
{
private IPublisher publisher;
public PublisherForm()
{
InitializeComponent();
publisher = new Publisher("tcp://127.0.0.1:8888");
} private void button1_Click(object sender, EventArgs e)
{
string strContent = textBox1.Text;
ListViewItem item = new ListViewItem(string.Format("topic:NetMQ,Data:{0}", strContent));
listView1.Items.Add(item);
publisher.Publish("NetMQ", strContent);
}
}
}
定义ISubscriber接口
namespace NetMQDemoSubscriber
{
public interface ISubscriber:IDisposable
{
/// <summary>
/// 事件
/// </summary>
event Action<string, string> Nofity; /// <summary>
/// 注册订阅主题
/// </summary>
/// <param name="topics"></param>
void RegisterSubscriber(List<string> topics); /// <summary>
/// 注册订阅
/// </summary>
void RegisterSbuscriberAll(); /// <summary>
/// 移除所有订阅消息,并关闭
/// </summary>
void RemoveSbuscriberAll();
}
}
Subscriber实现类
namespace NetMQDemoSubscriber
{
public class Subscriber:ISubscriber
{
private SubscriberSocket _subscriberSocket = null;
private string _endpoint = @"tcp://127.0.0.1:9876"; public Subscriber(string endPoint)
{
_subscriberSocket = new SubscriberSocket();
_endpoint = endPoint;
}
#region Implementation of IDisposable /// <summary>
/// 执行与释放或重置非托管资源相关的应用程序定义的任务。
/// </summary>
public void Dispose()
{
throw new NotImplementedException();
} #endregion #region Implementation of ISubscriber public event Action<string, string> Nofity = delegate { }; /// <summary>
/// 注册订阅主题
/// </summary>
/// <param name="topics"></param>
public void RegisterSubscriber(List<string> topics)
{
InnerRegisterSubscriber(topics);
} /// <summary>
/// 注册订阅
/// </summary>
public void RegisterSbuscriberAll()
{
InnerRegisterSubscriber();
} /// <summary>
/// 移除所有订阅消息,并关闭
/// </summary>
public void RemoveSbuscriberAll()
{
InnerStop();
} #endregion #region 内部实现 /// <summary>
/// 注册订阅消息
/// </summary>
/// <param name="topics">订阅的主题</param>
private void InnerRegisterSubscriber(List<string> topics = null)
{
InnerStop();
_subscriberSocket = new SubscriberSocket();
_subscriberSocket.Options.ReceiveHighWatermark = ;
_subscriberSocket.Connect(_endpoint);
if (null == topics)
{
_subscriberSocket.SubscribeToAnyTopic();
}
else
{
topics.ForEach(item => _subscriberSocket.Subscribe(item));
}
Task.Factory.StartNew(() =>
{
while (true)
{
string messageTopicReceived = _subscriberSocket.ReceiveFrameString();
string messageReceived = _subscriberSocket.ReceiveFrameString();
Nofity(messageTopicReceived, messageReceived);
}
});
} /// <summary>
/// 关闭订阅
/// </summary>
private void InnerStop()
{
_subscriberSocket.Close();
} #endregion
}
}
Subscriber窗口界面

窗体功能代码
namespace NetMQDemoSubscriber
{
public partial class SubscriberForm : Form
{
private ISubscriber subscriber;
public SubscriberForm()
{
InitializeComponent();
} private void SubscriberForm_Load(object sender, EventArgs e)
{
subscriber = new Subscriber("tcp://127.0.0.1:8888");
subscriber.RegisterSbuscriberAll();
subscriber.Nofity+= delegate(string s, string s1)
{
ListViewItem item = new ListViewItem(string.Format("topic:{0},Data:{1}", s, s1));
listView1.Items.Add(item);
};
}
}
}
运行后,Publiser开启一个,Subscirber开启三个,进行测试如图

如果觉得文章好,记得关注一下公众号哟!

NetMQ 发布订阅模式 Publisher-Subscriber的更多相关文章
- NetMQ(三): 发布订阅模式 Publisher-Subscriber
ZeroMQ系列 之NetMQ 一:zeromq简介 二:NetMQ 请求响应模式 Request-Reply 三:NetMQ 发布订阅模式 Publisher-Subscriber 四:NetMQ ...
- java 多线程 发布订阅模式:发布者java.util.concurrent.SubmissionPublisher;订阅者java.util.concurrent.Flow.Subscriber
1,什么是发布订阅模式? 在软件架构中,发布订阅是一种消息范式,消息的发送者(称为发布者)不会将消息直接发送给特定的接收者(称为订阅者).而是将发布的消息分为不同的类别,无需了解哪些订阅者(如果有的话 ...
- NetMQ发布订阅C#示例
NetMQ (ZeroMQ to .Net),ØMQ号称史上最快中间件.它对socket通信进行了封装,使得我们不需要写socket函数调用就能完成复杂的网络通信.和一般意义上的消息队列产品不同的是, ...
- redis的发布订阅模式pubsub
前言 redis支持发布订阅模式,在这个实现中,发送者(发送信息的客户端)不是将信息直接发送给特定的接收者(接收信息的客户端),而是将信息发送给频道(channel),然后由频道将信息转发给所有对这个 ...
- 观察者模式 vs 发布-订阅模式
我曾经在面试中被问道,_“观察者模式和发布订阅模式的有什么区别?” _我迅速回忆起“Head First设计模式”那本书: 发布 + 订阅 = 观察者模式 “我知道了,我知道了,别想骗我” 我微笑着回 ...
- js设计模式之发布/订阅模式模式
一.前言 发布订阅模式,基于一个主题/事件通道,希望接收通知的对象(称为subscriber)通过自定义事件订阅主题,被激活事件的对象(称为publisher)通过发布主题事件的方式被通知. 就和用户 ...
- js设计模式-发布/订阅模式
一.前言 发布订阅模式,基于一个主题/事件通道,希望接收通知的对象(称为subscriber)通过自定义事件订阅主题,被激活事件的对象(称为publisher)通过发布主题事件的方式被通知. 就和用户 ...
- js之观察者模式和发布订阅模式区别
观察者模式(Observer) 观察者模式指的是一个对象(Subject)维持一系列依赖于它的对象(Observer),当有关状态发生变更时 Subject 对象则通知一系列 Observer 对象进 ...
- 观察者模式Vs发布订阅模式
1)观察者模式 观察者模式通俗的讲就是我们平事件调用(click/change等等) 大家先看这个图片.我们被观察者Subject(监听某个事件)发生改变时,观察者Observer监听到没改变做出调整 ...
随机推荐
- 安装配置python环境,并跑一个推荐系统的例子
1.官网下载python2.7,安装完后,在环境变量Path中加上这个路径 在控制台输入python,出现版本信息,就成功了. 2.我使用的是 pycharm,注册后,在 把自己的python.exe ...
- python08内置函数
https://www.cnblogs.com/xiao1/p/5856890.html 1 .all(可迭代对象),对每个元素进行布尔运算,全部为真,函数结果就为真,否则为假 参数为一个整体的情况例 ...
- [Python] 怎么把HTML的报告转换为图片,利用无头浏览器
How to convert HTML Report to picture format in Email? So that we can see the automation report also ...
- Firefox录制时浏览器提示代理服务器拒绝连接
解决方法:检查火狐浏览器的代理设置是否正确,在 菜单栏 工具->选项->高级->网络->连接->设置里.将“配置访问因特网的代理”选项改为“无代理”.
- selenium实现淘宝的商品爬取
一.问题 本次利用selenium自动化测试,完成对淘宝的爬取,这样可以避免一些反爬的措施,也是一种爬虫常用的手段.本次实战的难点: 1.如何利用selenium绕过淘宝的登录界面 2.获取淘宝的页面 ...
- 什么是servlet?
一.servlet是什么? 是用java编写的应用在服务端的程序,具有独立于平台和协议的特性,主要功能在于交互式地浏览和修改数据,生成动态Web内容,例如页面等等.从实现上讲,Servlet可以响应任 ...
- 曙光服务器挂载EMC存储
1.登录集群(用户名密码远程登录,然后切换到root用户) 2.连接主机:ssh node72 3.在主机下进行存储挂载: 1)fdisk -l 查看磁盘信息,如下图所示: 2)查看磁盘挂载信息:mo ...
- 修改chrome浏览器默认css样式的方法
最近重新用起了ubuntu kylin,然后又碰到之前让我感到有些难受的一个小问题:用chrome浏览部分网页时,一部分粗体字十分难看,就像是宋体直接加粗那样. 之前就觉得这样看起来很难受,但是找到的 ...
- Ubuntu 14.04 LTS 下使用校园网客户端DrclientLinux
原先博客放弃使用,几篇文章搬运过来 下载客户端并解压 安装开发包 sudo -i dpkg --add-architecture i386 #添加32位的支持 apt-get update apt-g ...
- 内置函数_zip()
zip() zip()函数用来把多个可迭代对象中的元素压缩到一起,返回一个可迭代的zip对象,其中每个元素都是包含原来的多个可迭代对象对应位置上元素的元组,最终结果中包含的元素个数取决于所有参数序列或 ...