第一部分引用于:点击打开

1:简单介绍

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


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


图2:与请求响应模式组合的发布订阅模式

2:案例

定义IPublishser接口

  1. namespace NetMQDemoPublisher
  2. {
  3. public interface IPublisher:IDisposable
  4. {
  5. /// <summary>
  6. /// 发布消息
  7. /// </summary>
  8. /// <param name="topicName">主题</param>
  9. /// <param name="data">内容</param>
  10. void Publish(string topicName, string data);
  11. }
  12. }

Publisher实现类

  1. namespace NetMQDemoPublisher
  2. {
  3. public class Publisher:IPublisher
  4. {
  5. private object _lockObject = new object();
  6.  
  7. private PublisherSocket _publisherSocket;
  8.  
  9. public Publisher(string endPoint)
  10. {
  11. _publisherSocket = new PublisherSocket();
  12. _publisherSocket.Options.SendHighWatermark = ;
  13. _publisherSocket.Bind(endPoint);
  14. }
  15. #region Implementation of IDisposable
  16.  
  17. /// <summary>
  18. /// 执行与释放或重置非托管资源相关的应用程序定义的任务。
  19. /// </summary>
  20. public void Dispose()
  21. {
  22. lock (_lockObject)
  23. {
  24. _publisherSocket.Close();
  25. _publisherSocket.Dispose();
  26. }
  27. }
  28.  
  29. /// <summary>
  30. /// 发布消息
  31. /// </summary>
  32. /// <param name="topicName">主题</param>
  33. /// <param name="data">内容</param>
  34. public void Publish(string topicName, string data)
  35. {
  36. lock (_lockObject)
  37. {
  38. _publisherSocket.SendMoreFrame(topicName).SendFrame(data);
  39. }
  40. }
  41.  
  42. #endregion
  43. }
  44. }

Publisher窗口界面

界面中实现的功能代码

  1. namespace NetMQDemoPublisher
  2. {
  3. public partial class PublisherForm : Form
  4. {
  5. private IPublisher publisher;
  6. public PublisherForm()
  7. {
  8. InitializeComponent();
  9. publisher = new Publisher("tcp://127.0.0.1:8888");
  10. }
  11.  
  12. private void button1_Click(object sender, EventArgs e)
  13. {
  14. string strContent = textBox1.Text;
  15. ListViewItem item = new ListViewItem(string.Format("topic:NetMQ,Data:{0}", strContent));
  16. listView1.Items.Add(item);
  17. publisher.Publish("NetMQ", strContent);
  18. }
  19. }
  20. }

定义ISubscriber接口

  1. namespace NetMQDemoSubscriber
  2. {
  3. public interface ISubscriber:IDisposable
  4. {
  5. /// <summary>
  6. /// 事件
  7. /// </summary>
  8. event Action<string, string> Nofity;
  9.  
  10. /// <summary>
  11. /// 注册订阅主题
  12. /// </summary>
  13. /// <param name="topics"></param>
  14. void RegisterSubscriber(List<string> topics);
  15.  
  16. /// <summary>
  17. /// 注册订阅
  18. /// </summary>
  19. void RegisterSbuscriberAll();
  20.  
  21. /// <summary>
  22. /// 移除所有订阅消息,并关闭
  23. /// </summary>
  24. void RemoveSbuscriberAll();
  25. }
  26. }

Subscriber实现类

  1. namespace NetMQDemoSubscriber
  2. {
  3. public class Subscriber:ISubscriber
  4. {
  5. private SubscriberSocket _subscriberSocket = null;
  6. private string _endpoint = @"tcp://127.0.0.1:9876";
  7.  
  8. public Subscriber(string endPoint)
  9. {
  10. _subscriberSocket = new SubscriberSocket();
  11. _endpoint = endPoint;
  12. }
  13. #region Implementation of IDisposable
  14.  
  15. /// <summary>
  16. /// 执行与释放或重置非托管资源相关的应用程序定义的任务。
  17. /// </summary>
  18. public void Dispose()
  19. {
  20. throw new NotImplementedException();
  21. }
  22.  
  23. #endregion
  24.  
  25. #region Implementation of ISubscriber
  26.  
  27. public event Action<string, string> Nofity = delegate { };
  28.  
  29. /// <summary>
  30. /// 注册订阅主题
  31. /// </summary>
  32. /// <param name="topics"></param>
  33. public void RegisterSubscriber(List<string> topics)
  34. {
  35. InnerRegisterSubscriber(topics);
  36. }
  37.  
  38. /// <summary>
  39. /// 注册订阅
  40. /// </summary>
  41. public void RegisterSbuscriberAll()
  42. {
  43. InnerRegisterSubscriber();
  44. }
  45.  
  46. /// <summary>
  47. /// 移除所有订阅消息,并关闭
  48. /// </summary>
  49. public void RemoveSbuscriberAll()
  50. {
  51. InnerStop();
  52. }
  53.  
  54. #endregion
  55.  
  56. #region 内部实现
  57.  
  58. /// <summary>
  59. /// 注册订阅消息
  60. /// </summary>
  61. /// <param name="topics">订阅的主题</param>
  62. private void InnerRegisterSubscriber(List<string> topics = null)
  63. {
  64. InnerStop();
  65. _subscriberSocket = new SubscriberSocket();
  66. _subscriberSocket.Options.ReceiveHighWatermark = ;
  67. _subscriberSocket.Connect(_endpoint);
  68. if (null == topics)
  69. {
  70. _subscriberSocket.SubscribeToAnyTopic();
  71. }
  72. else
  73. {
  74. topics.ForEach(item => _subscriberSocket.Subscribe(item));
  75. }
  76. Task.Factory.StartNew(() =>
  77. {
  78. while (true)
  79. {
  80. string messageTopicReceived = _subscriberSocket.ReceiveFrameString();
  81. string messageReceived = _subscriberSocket.ReceiveFrameString();
  82. Nofity(messageTopicReceived, messageReceived);
  83. }
  84. });
  85. }
  86.  
  87. /// <summary>
  88. /// 关闭订阅
  89. /// </summary>
  90. private void InnerStop()
  91. {
  92. _subscriberSocket.Close();
  93. }
  94.  
  95. #endregion
  96. }
  97. }

Subscriber窗口界面

窗体功能代码

  1. namespace NetMQDemoSubscriber
  2. {
  3. public partial class SubscriberForm : Form
  4. {
  5. private ISubscriber subscriber;
  6. public SubscriberForm()
  7. {
  8. InitializeComponent();
  9. }
  10.  
  11. private void SubscriberForm_Load(object sender, EventArgs e)
  12. {
  13. subscriber = new Subscriber("tcp://127.0.0.1:8888");
  14. subscriber.RegisterSbuscriberAll();
  15. subscriber.Nofity+= delegate(string s, string s1)
  16. {
  17. ListViewItem item = new ListViewItem(string.Format("topic:{0},Data:{1}", s, s1));
  18. listView1.Items.Add(item);
  19. };
  20. }
  21. }
  22. }

运行后,Publiser开启一个,Subscirber开启三个,进行测试如图

源码下载

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

NetMQ 发布订阅模式 Publisher-Subscriber的更多相关文章

  1. NetMQ(三): 发布订阅模式 Publisher-Subscriber

    ZeroMQ系列 之NetMQ 一:zeromq简介 二:NetMQ 请求响应模式 Request-Reply 三:NetMQ 发布订阅模式 Publisher-Subscriber 四:NetMQ ...

  2. java 多线程 发布订阅模式:发布者java.util.concurrent.SubmissionPublisher;订阅者java.util.concurrent.Flow.Subscriber

    1,什么是发布订阅模式? 在软件架构中,发布订阅是一种消息范式,消息的发送者(称为发布者)不会将消息直接发送给特定的接收者(称为订阅者).而是将发布的消息分为不同的类别,无需了解哪些订阅者(如果有的话 ...

  3. NetMQ发布订阅C#示例

    NetMQ (ZeroMQ to .Net),ØMQ号称史上最快中间件.它对socket通信进行了封装,使得我们不需要写socket函数调用就能完成复杂的网络通信.和一般意义上的消息队列产品不同的是, ...

  4. redis的发布订阅模式pubsub

    前言 redis支持发布订阅模式,在这个实现中,发送者(发送信息的客户端)不是将信息直接发送给特定的接收者(接收信息的客户端),而是将信息发送给频道(channel),然后由频道将信息转发给所有对这个 ...

  5. 观察者模式 vs 发布-订阅模式

    我曾经在面试中被问道,_“观察者模式和发布订阅模式的有什么区别?” _我迅速回忆起“Head First设计模式”那本书: 发布 + 订阅 = 观察者模式 “我知道了,我知道了,别想骗我” 我微笑着回 ...

  6. js设计模式之发布/订阅模式模式

    一.前言 发布订阅模式,基于一个主题/事件通道,希望接收通知的对象(称为subscriber)通过自定义事件订阅主题,被激活事件的对象(称为publisher)通过发布主题事件的方式被通知. 就和用户 ...

  7. js设计模式-发布/订阅模式

    一.前言 发布订阅模式,基于一个主题/事件通道,希望接收通知的对象(称为subscriber)通过自定义事件订阅主题,被激活事件的对象(称为publisher)通过发布主题事件的方式被通知. 就和用户 ...

  8. js之观察者模式和发布订阅模式区别

    观察者模式(Observer) 观察者模式指的是一个对象(Subject)维持一系列依赖于它的对象(Observer),当有关状态发生变更时 Subject 对象则通知一系列 Observer 对象进 ...

  9. 观察者模式Vs发布订阅模式

    1)观察者模式 观察者模式通俗的讲就是我们平事件调用(click/change等等) 大家先看这个图片.我们被观察者Subject(监听某个事件)发生改变时,观察者Observer监听到没改变做出调整 ...

随机推荐

  1. python加密解密算法

    https://www.cnblogs.com/xiao-apple36/p/8744408.html

  2. Luogu3119 草鉴定-Tarjan+Topsort

    Solution 简单的$Tarjan$题. 有大佬现成博客 就不写了 → 传送门 Code #include<cstdio> #include<cstring> #inclu ...

  3. vue中的import、export、requre的区别

    在es6之前js一直没有自己的模块语法,为了解决这种尴尬就有了require.js的出现.在es6发布之后js又引入了import的概念使得不清楚两者之间的区别的同学在实际使用过程中造成了自己的误解, ...

  4. 谷歌发布了 T2T(Tensor2Tensor)深度学习开源系统

    谷歌开源T2T模型库,深度学习系统进入模块化时代! 谷歌大脑颠覆深度学习混乱现状,要用单一模型学会多项任务 https://github.com/tensorflow/models https://g ...

  5. 20175316盛茂淞 2018-2019-2《Java程序设计》第4周学习总结

    20175316盛茂淞 2018-2019-2<Java程序设计>第4周学习总结 教材学习内容总结 第五章 子类与继承 一.继承 1.继承定义:避免多个类间重复定义共同行为 2.子类与父类 ...

  6. VM下载安装

    VM下载 VM是一款收费软件,要找有密钥的下载. 我的网盘 > 软件 > 常用电脑工具 > VM VM安装 参考链接中的安装步骤 http://blog.java1234.com/b ...

  7. Oracle DBLINk的使用

    Oracle中自带了DBLink功能,它的作用是将多个oracle数据库逻辑上看成一个数据库,也就是说在一个数据库中可以操作另一个数据库中的对象,例如我们新建了一个数据database1,我们需要操作 ...

  8. android-基础编程-ExpandableListview

    ExpandableListView继承ListView,具有LIstVIew的基本功能.此外具有group/child,由组与子元素组成. 1.布局主要有是三个. a.主布局: <Expand ...

  9. 向jsp中引入公共文件

    前沿,在网页开发中,总会存在某几个.js或者某几个.css是所有.jsp文件的公用文件,为了方便引用 我们把这些在公共的.js及.css文件放到一个.jsp文件中,只需要将这个引入所有公共.js及.c ...

  10. Centos6.5安装中文支持和中文输入法

     先来讲中文支持:    之前在网上查了不少资料,很多网友在网上都说,在shell命令下输入: # vi /etc/sysconfig/i18n 然后修改LANG="en_US.UTF-8& ...