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

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的更多相关文章

  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. MongoDB 官网教程 下载 安装

    官网:https://www.mongodb.com/ Doc:https://docs.mongodb.com/ Manual:https://docs.mongodb.com/manual/ 安装 ...

  2. pycharm 2017最新激活码

    BIG3CLIK6F-eyJsaWNlbnNlSWQiOiJCSUczQ0xJSzZGIiwibGljZW5zZWVOYW1lIjoibGFuIHl1IiwiYXNzaWduZWVOYW1lIjoiI ...

  3. M1卡知识点描述

  4. OpenCV+Qt+CMake安装+十种踩坑

    平台:win10 x64+opencv-3.4.1 + qt-x86-5.9.0 + cmake3.13.4 x64 OpenCV+Qt+CMake安装,及目前安装完后打包:mingw32-make时 ...

  5. file 上传大小限制问题

    今天突然传了一张很大的图片 结果怎么传都获取不到信息(如下); 最后查看了下php.ini 中的 " upload_max_filesize  "最大只允许了2M!  改下就可以 ...

  6. ABP框架系列之二十九:(Hangfire-Integration-延迟集成)

    Introduction Hangfire is a compherensive background job manager. You can integrate ASP.NET Boilerpla ...

  7. Maven二

    1 回顾 1.1 Maven的好处 节省空间 对jar包做了统一管理 依赖管理 一键构建 可跨平台 应用在大型项目可提高开发效率 1.2 Maven安装部署配置 1.3 Maven的仓库 本地仓库 远 ...

  8. jquery print属性设置

    一,需求背景 项目中遇到打印功能,想实现完美的打印功能,对元素进行操作等,可以使用jquery print 插件. 二,依赖文件  git地址请戳这里 1,jquery 2,jquery.print- ...

  9. canvas 旋转

    <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...

  10. Spring 使用xml配置aop

    1.xml文件需要引入aop命名空间 2.xml内容: <?xml version="1.0" encoding="UTF-8"?> <bea ...