【EasyNetQ】- 订阅
EasyNetQ订阅者订阅消息类型(消息类的.NET类型)。一旦通过调用Subscribe方法设置了对类型的订阅,就会在RabbitMQ代理上创建一个持久队列,并且该类型的任何消息都将被放置在队列中。只要连接,RabbitMQ就会将任何消息从队列发送给用户。
要订阅消息,我们需要为EasyNetQ提供在消息到达时执行的操作。我们通过传递订阅委托来做到这一点:
bus.Subscribe<MyMessage>("my_subscription_id", msg => Console.WriteLine(msg.Text));
现在每次发布MyMessage实例时,EasyNetQ都会调用我们的委托并将消息的Text属性打印到控制台。
您传递给Subscribe的订阅ID很重要。EasyNetQ将在RabbitMQ代理上为消息类型和订阅ID的每个唯一组合创建一个唯一的队列。
每次调用Subscribe都会创建一个新的队列使用者。如果使用相同的消息类型和订阅ID调用“订阅”两次,则将创建两个使用相同队列的消费者。然后RabbitMQ将依次循环连续消息给每个消费者。这非常适合扩展和工作共享。假设您已经创建了一个处理特定消息的服务,但它的工作负担过重。只需启动该服务的新实例(在同一台机器上,或在不同的机器上),无需配置任何内容,您就可以自动扩展。
如果使用不同的订阅ID(但具有相同的消息类型)两次调用“订阅”,则将创建两个队列,每个队列都有自己的使用者。给定类型的每条消息的副本将被路由到每个队列,因此每个消费者将获得所有消息(该类型的消息)。如果你有几个不同的服务都关心相同的消息类型,这是很好的。
编写订阅回调委托时的注意事项
当从通过EasyNetQ订阅的队列接收消息时,它们被放置在内存中队列中。单个线程位于一个循环中,从队列中获取消息并调用其Action代理。由于在单个线程上一次处理一个委托,因此应避免长时间运行的同步IO操作。尽快从代表处返回控制权。
使用SubscribeAsync
SubscribeAsync允许您的订阅者委托立即返回任务,然后异步执行长时间运行的IO操作。完成长期订阅后,只需完成任务即可。在下面的示例中,我们使用异步IO操作(DownloadStringTask)向Web服务发出请求。任务完成后,我们在控制台上写一行。
bus.SubscribeAsync<MyMessage>("subscribe_async_test", message =>
new WebClient().DownloadStringTask(new Uri("http://localhost:1338/?timeout=500"))
.ContinueWith(task =>
Console.WriteLine("Received: '{0}', Downloaded: '{1}'",
message.Text,
task.Result)));
另一个示例将导致在出现错误时抛出异常,然后导致消息被置于缺省错误队列中:
_bus.SubscribeAsync<MessageType>("Queue_Identifier",
message => Task.Factory.StartNew(() =>
{
// Perform some actions here
// If there is a exception it will result in a task complete but task faulted which
// is dealt with below in the continuation
}).ContinueWith(task =>
{
if (task.IsCompleted && !task.IsFaulted)
{
// Everything worked out ok
}
else
{
// Dont catch this, it is caught further up the heirarchy and results in being sent to the default error queue
// on the broker
throw new EasyNetQException("Message processing exception - look in the default error queue (broker)");
}
}));
取消订阅
所有subscribe方法都返回一个ISubscriptionResult。它包含描述底层IConsumerIExchange
和IQueue
使用的属性,如果需要,可以使用高级API进一步操作这些属性。IAdvancedBus
您可以通过在ISubscriptionResult
实例或其ConsumerCancellation
属性上调用Dispose来随时取消订阅者:
var subscriptionResult = bus.Subscribe<MyMessage>("sub_id", MyHandler); ... subscriptionResult.Dispose();
// this is equivalent to subscriptionResult.ConsumerCancellation.Dispose();
这将阻止EasyNetQ从队列中消耗并关闭消费者的频道。
请注意,处理IBus
或IAdvancedBus
实例也将取消所有使用者并关闭与RabbitMQ的连接。
难道不叫subscriptionResult.Dispose()
一个消息处理程序内。这将在EasyNetQ确认消费者频道上的消息subscriptionResult.Dispose()
与关闭该频道的呼叫之间产生竞争条件。由于EasyNetQ的内部架构,这些调用将在不同的线程上调用,并且时序不确定。
【EasyNetQ】- 订阅的更多相关文章
- 3,EasyNetQ-发布/订阅
一.发布 在发布/订阅模式中的角色是彼此陌生的. 一个发布者只是向世界说这个已经发生了,一位订阅者告诉世界“我在乎这个”. 在这个模型中,没有人关心特定的事件是很好的. 消息可能有一个订阅者,可能有2 ...
- 【EasyNetQ】- 请求回复
EasyNetQ还支持请求/响应消息传递模式.这使得实现客户端/服务器应用程序变得容易,客户端向服务器发出请求,然后服务器处理请求并返回响应.与传统的RPC机制不同,EasyNetQ请求/响应操作没有 ...
- 6-EasyNetQ之订阅
一个EasyNetQ订阅者订阅一种消息类型(消息类为.NET 类型).通过调用Subcribe方法一旦对一个类型设置了订阅,一个持久化队列就会在RabbitMQ broker上被创建,这个类型的任何消 ...
- EasyNetQ使用(四)【Request与Response,Send与Receive】
EasyNetQ也支持Request/Response这种方式的消息模式.这种方式很容易在client/Server应用中执行,客户端发送一个请求到服务器,服务器然后处理请求后返回一个响应.和传统的R ...
- EasyNetQ使用(三)【Publish与Subcribe】
EasyNetQ支持的最简单的消息模式是发布/订阅.这个模式是一个极好的方法用来解耦消息提供者和消费者.消息发布者只要简单的对世界说,“这里有些事发生” 或者 “我现在有一个信息”.它不关心有没有人监 ...
- 4,EasyNetQ-Request Response
EasyNetQ还支持请求/响应消息传递模式. 这使得客户端/服务器应用程序变得容易,客户机/服务器应用程序在客户端向服务器发出请求,然后处理请求并返回响应. 与传统的RPC机制不同,EasyNetQ ...
- 7-EasyNetQ之Request & Response
EasyNetQ也支持Request/Response这种方式的消息模式.这种方式很容易在client/Server应用中执行,客户端发送一个请求到服务器,服务器然后处理请求后返回一个响应.和传统的R ...
- EasyNetQ之多态发布和订阅
你能够订阅一个接口,然后发布基于这个接口的实现. 让我们看下一个示例.我有一个接口IAnimal和两个实现Cat和Dog: public interface IAnimal { string Name ...
- easynetq发布订阅demo实现注意事项
最近开始在项目中使用easynetq,大概了解了下api,在网上看了下示例,结果没有一个运行成功的,一个最简单的发布订阅都没有成功.我是直接运行起来别人的示例,不应该啊,后来一直分析一直分析,最后发现 ...
随机推荐
- CentOS上安装oracle11g报错处理
最近,在处理oracle gateway的报错问题.只因个人的测试环境已经迁移到docker上了,又懒得装一套环境就直接在机器上安装oracle11g.今天分享的故事就从此开始-- 运行环境 项目 ...
- JS高度融合入门笔记(二)
<!DOCTYPE html><html><head> <meta charset="utf-8"> <title>JS ...
- 【ISIS(中间系统到中间系统)路由链路状态信息协议初识】
ISIS单区域的基本配置 一:根据项目需求,考虑到组网的规模和条件,部署ISIS单区域的拓扑图如下: 二:配置 1:首先对RTA进行配置,在系统视图创建ISIS进程:进入ISIS配置视图,指定IS的级 ...
- php 删除富文本编辑器保存内容中的其他代码(保留中文)
$str = '<p><p style="ve:"">测试筛选文本域内的中文 </p><p sty;"> ...
- echarts实用小技巧,控制字符串长度,限定整数等
限定横坐标文本字符长度 xAxis : [ axisLabel:{ formatter: function (value) { var maxlength=6; if (value.length> ...
- JavaScript之DOM查询
DOM查询 - 通过具体的元素节点来查询 - 元素.getElementsByTagName() - 通过标签名查询当前元素的指定后代元素,返回数组 - 元素.childNodes - 获取当前元素的 ...
- 为什么我要放弃javaScript数据结构与算法(第一章)—— JavaScript简介
数据结构与算法一直是我算比较薄弱的地方,希望通过阅读<javaScript数据结构与算法>可以有所改变,我相信接下来的记录不单单对于我自己有帮助,也可以帮助到一些这方面的小白,接下来让我们 ...
- 查询如下课程平均成绩和及格率的百分数(用"1行"显示): 企业管理(001),马克思(002),OO&UML (003),数据库(004)
SELECT SUM(CASE WHEN C# ='001' THEN score ELSE 0 END)/SUM(CASE C# WHEN '001' THEN 1 ELSE 0 END) AS 企 ...
- hdu4742 Pinball Game 3D
真他娘的搞不懂cdq分治的顺序问题.但是candy?的博客里提到过,多想想吧-- #include <algorithm> #include <iostream> #inclu ...
- 用Kettle的一套流程完成对整个数据库迁移 费元星
原地址 :http://ainidehsj.iteye.com/blog/1735434 需求: 1.你是否遇到了需要将mysql数据库中的所有表与数据迁移到Oracle. 2.你是否还在使用kett ...