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。它包含描述底层IConsumerIExchangeIQueue使用的属性,如果需要,可以使用高级API进一步操作这些属性。IAdvancedBus

您可以通过在ISubscriptionResult实例或其ConsumerCancellation属性上调用Dispose来随时取消订阅者:

var subscriptionResult = bus.Subscribe<MyMessage>("sub_id", MyHandler);

...

subscriptionResult.Dispose();
// this is equivalent to subscriptionResult.ConsumerCancellation.Dispose();

这将阻止EasyNetQ从队列中消耗并关闭消费者的频道。

请注意,处理IBusIAdvancedBus实例也将取消所有使用者并关闭与RabbitMQ的连接。

难道不叫subscriptionResult.Dispose()一个消息处理程序内。这将在EasyNetQ确认消费者频道上的消息subscriptionResult.Dispose()与关闭该频道的呼叫之间产生竞争条件。由于EasyNetQ的内部架构,这些调用将在不同的线程上调用,并且时序不确定。

【EasyNetQ】- 订阅的更多相关文章

  1. 3,EasyNetQ-发布/订阅

    一.发布 在发布/订阅模式中的角色是彼此陌生的. 一个发布者只是向世界说这个已经发生了,一位订阅者告诉世界“我在乎这个”. 在这个模型中,没有人关心特定的事件是很好的. 消息可能有一个订阅者,可能有2 ...

  2. 【EasyNetQ】- 请求回复

    EasyNetQ还支持请求/响应消息传递模式.这使得实现客户端/服务器应用程序变得容易,客户端向服务器发出请求,然后服务器处理请求并返回响应.与传统的RPC机制不同,EasyNetQ请求/响应操作没有 ...

  3. 6-EasyNetQ之订阅

    一个EasyNetQ订阅者订阅一种消息类型(消息类为.NET 类型).通过调用Subcribe方法一旦对一个类型设置了订阅,一个持久化队列就会在RabbitMQ broker上被创建,这个类型的任何消 ...

  4. EasyNetQ使用(四)【Request与Response,Send与Receive】

    EasyNetQ也支持Request/Response这种方式的消息模式.这种方式很容易在client/Server应用中执行,客户端发送一个请求到服务器,服务器然后处理请求后返回一个响应.和传统的R ...

  5. EasyNetQ使用(三)【Publish与Subcribe】

    EasyNetQ支持的最简单的消息模式是发布/订阅.这个模式是一个极好的方法用来解耦消息提供者和消费者.消息发布者只要简单的对世界说,“这里有些事发生” 或者 “我现在有一个信息”.它不关心有没有人监 ...

  6. 4,EasyNetQ-Request Response

    EasyNetQ还支持请求/响应消息传递模式. 这使得客户端/服务器应用程序变得容易,客户机/服务器应用程序在客户端向服务器发出请求,然后处理请求并返回响应. 与传统的RPC机制不同,EasyNetQ ...

  7. 7-EasyNetQ之Request & Response

    EasyNetQ也支持Request/Response这种方式的消息模式.这种方式很容易在client/Server应用中执行,客户端发送一个请求到服务器,服务器然后处理请求后返回一个响应.和传统的R ...

  8. EasyNetQ之多态发布和订阅

    你能够订阅一个接口,然后发布基于这个接口的实现. 让我们看下一个示例.我有一个接口IAnimal和两个实现Cat和Dog: public interface IAnimal { string Name ...

  9. easynetq发布订阅demo实现注意事项

    最近开始在项目中使用easynetq,大概了解了下api,在网上看了下示例,结果没有一个运行成功的,一个最简单的发布订阅都没有成功.我是直接运行起来别人的示例,不应该啊,后来一直分析一直分析,最后发现 ...

随机推荐

  1. 最长公共子序列Lcs (51Nod - 1006)

    20180604   11:28   给出两个字符串A B,求A与B的最长公共子序列(子序列不要求是连续的).   比如两个串为:   abcicba abdkscab   ab是两个串的子序列,ab ...

  2. ABAP术语-Customer Exit

    Customer Exit 原文:http://www.cnblogs.com/qiangsheng/archive/2008/01/19/1045231.html Pre-planned enhan ...

  3. python实践项目—Collatz序列

    Collatz序列题意说明 编写一个名为collatz()的函数,它有一个名为number 的参数.如果参数是偶数,那么collatz()就打印出number // 2,并返回该值.如果number ...

  4. svg在html的使用

    <svg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'> <defs&g ...

  5. jdk与tomcat的环境配置

    一.JDK的安装与配置 1.从官网下载jdk,注意是jdk不是jre.最好从官网下载,也可以直接度娘. 2.下载完毕后,安装jdk,​直接按照安装向导的提示安装即可,安装时可以自己选择安装路径,我的安 ...

  6. input输入框类型

    输入大小写字母.数字.下划线: <input type="text" onkeyup="this.value=this.value.replace(/[^\w_]/ ...

  7. 学习photoshop心得

    简要的学习了ps的三大功能p图,抠图,作图, p图主要是学了换脸这一效果,用到套索工具,把范冰冰的脸接到郭德纲身上, 首先使用套索工具把脸圈起来 然后移动到 另一个人脸上 再然后混合图层,自动混合 差 ...

  8. mysql5.7数据库与5.7之前版本比较

    数据库初始化方式变更 <5.7 版本 mysql_install_db >5.7 版本 bin/mysqld --initialize --user =mysql --basedir=/u ...

  9. phpcms2008网站漏洞如何修复 远程代码写入缓存漏洞利用

    SINE安全公司在对phpcms2008网站代码进行安全检测与审计的时候发现该phpcms存在远程代码写入缓存文件的一个SQL注入漏洞,该phpcms漏洞危害较大,可以导致网站被黑,以及服务器遭受黑客 ...

  10. Electronic Devices【电子设备】

    Electronic Devices We may think we're a culture that gets rid of our worn technology at the first si ...