12,EasyNetQ-自动订阅
EasyNetQ自v0.7.1.30附带一个简单的AutoSubscriber。 您可以使用它轻松扫描实现接口IConsume <T>或IConsumeAsync <T>的类的特定程序集,然后让自动订户将这些使用者订阅到您的总线。 IConsume <T>的实现将使用总线Subscribe方法,而IConsumeAsync <T>的实现将使用总线SubscribeAsync方法,请参阅Subscribe以了解详细信息。 你当然可以让你的消费者处理多个消息。 我们来看看一些样品。
注意:从版本0.13.0开始,所有AutoSubscriber类都位于EasyNetQ.AutoSubscribe命名空间中,因此请添加以下using语句: using EasyNetQ.AutoSubscribe;
让我们定义一个简单的消费者,处理三条消息:MessageA, MessageB and MessageC.
public class MyConsumer : IConsume<MessageA>, IConsume<MessageB>, IConsumeAsync<MessageC>
{
public void Consume(MessageA message) {...} public void Consume(MessageB message) {...} public Task Consume(MessageC message) {...}
}
首先创建AutoSubscriber的新实例,将IBus实例和subscriptionId前缀传递给构造函数。 subscriptionId前缀的前缀是所有自动生成的subscriptionIds,但不是自定义subscriptionIds(请参见下文)。
为了注册这个以及同一个Assembly中的所有其他使用者,我们只需要将包含您的使用者的程序集传递给:AutoSubscriber.Subscribe(assembly)。 注意! 这是你应该只做一次,最好在应用程序启动时。
var subscriber = new AutoSubscriber(bus, "my_applications_subscriptionId_prefix");
subscriber.Subscribe(Assembly.GetExecutingAssembly());
1,通过主题订阅(s)
默认情况下,AutoSubscriber将绑定无主题。 在下面的示例中,MessageA注册了两个主题。
注意! 如果你运行没有ForTopic属性的代码,它将有一个“#”的路由键,它将接收任何消息类型的订阅。 假设安装了默认端口和管理插件,只需访问http:// localhost:15672 /#/队列并根据需要解除绑定即可。
public class MyConsumer : IConsume<MessageA>, IConsume<MessageB>, IConsumeAsync<MessageC>
{
[ForTopic("Topic.Foo")]
[ForTopic("Topic.Bar")]
public void Consume(MessageA message) {...} public void Consume(MessageB message) {...} public Task Consume(MessageC message) {...}
} //To publish by topic
var bus = RabbitHutch.CreateBus("host=localhost"); var msg1 = new MessageA(msg1, "Topic.Foo"); //picked up
var msg2 = new MessageA(msg2, "Topic.Bar"); //picked up
var msg3 = new MessageA(msg3); //not picked up
2,指定一个特定的SubscriptionId
默认情况下,AutoSubscriber将为每个消息/消费者组合生成唯一的SubscriptionId。 这意味着您将启动同一个使用者的多个实例,并且它们将以循环方式(工作模式)从相同的队列中读取。
如果您希望修订订阅ID,则可以使用AutoSubscriberConsumerAttribute修饰Consume方法。 为什么你会修正它,你可以在这里阅读。
比方说,上面的消费者应该有一个固定的SubscriptionId用于MessageB的消费者方法。 刚刚装饰它并为SubscriptionId定义一个值。
[AutoSubscriberConsumer(SubscriptionId = "MyExplicitId")]
public void Consume(MessageB message) { }
3,控制SubscriptionId生成
您当然也可以控制实际的SubscriptionId生成。 只需替换AutoSubscriber.GenerateSubscriptionId:Func <ConsumerInfo,string>。
var subscriber = new AutoSubscriber(bus)
{
CreateConsumer = t => objectResolver.Resolve(t),
GenerateSubscriptionId = c => AppDomain.CurrentDomain.FriendlyName + c.ConcreteType.Name
};
subscriber.Subscribe(Assembly.GetExecutingAssembly());
注意! 只是一个示例实现。 确保您已阅读并理解SubscriptionId值的重要性。
4,控制消费者配置设置
使用自动订阅服务器订阅队列时,可以设置ISubscriptionConfiguration值,例如AutoDelete,Priority等。
通过在创建AutoSubscriber时设置操作。
var subscriber = new AutoSubscriber(bus)
{
ConfigureSubscriptionConfiguration = c => c.WithAutoDelete()
.WithPriority()
};
subscriber.Subscribe(Assembly.GetExecutingAssembly());
或者,您可以将一个属性应用于使用方法,该方法优先于ConfigureSubscriptionConfiguration操作设置的任何配置值。
public class MyConsumer : IConsume<MessageA>
{
[SubscriptionConfiguration(CancelOnHaFailover = true, PrefetchCount = )]
public void Consume(MessageA message) {...}
}
5,在AutoSubscriber中使用IoC容器
AutoSubscriber有一个属性MessageDispatcher,它允许您插入自己的消息分派代码。 这使您可以从IoC容器中解析消费者或执行其他自定义调度时间任务。
我们编写一个定制的IAutoSubscriberMessageDispatcher来解析Windsor IoC容器中的消费者
public class WindsorMessageDispatcher : IAutoSubscriberMessageDispatcher
{
private readonly IWindsorContainer container; public WindsorMessageDispatcher(IWindsorContainer container)
{
this.container = container;
} public void Dispatch<TMessage, TConsumer>(TMessage message) where TMessage : class where TConsumer : IConsume<TMessage>
{
var consumer = container.Resolve<TConsumer>();
try
{
consumer.Consume(message);
}
finally
{
container.Release(consumer);
}
} public Task DispatchAsync<TMessage, TConsumer>(TMessage message) where TMessage: class where TConsumer: IConsumeAsync<TMessage>
{
var consumer = _container.Resolve<TConsumer>();
return consumer.Consume(message).ContinueWith(t=>_container.Release(consumer));
}
}
现在我们需要在我们的IoC容器中注册我们的客户:
var container = new WindsorContainer();
container.Register(
Component.For<MyConsumer>().ImplementedBy<MyConsumer>()
);
接下来使用我们的自定义IMessageDispatcher设置AutoSubscriber:
var bus = RabbitHutch.CreateBus("host=localhost");
var autoSubscriber = new AutoSubscriber(bus, "My_subscription_id_prefix")
{
MessageDispatcher = new WindsorMessageDispatcher(container)
};
autoSubscriber.Subscribe(GetType().Assembly);
autoSubscriber.SubscribeAsync(GetType().Assembly);
现在,每次收到消息时,我们的消费者的新实例都将从我们的容器中解析出来。
12,EasyNetQ-自动订阅的更多相关文章
- EasyNetQ使用(八)【对延迟消息插件的支持,自动订阅者】
RabbitMQ延迟消息插件仍然在实验阶段.你使用这个功能要自担风险. RabbitMQ延迟消息插件为RabbitMQ增加了新的交换机类型,允许延时消息投递. EasyNetQ为交换机通过定义一种新的 ...
- 16-EasyNetQ之自动订阅者
EasyNetQ v0.7.1.30版本有了一个简单AutoSubscriber.你能够使用它很容易的去扫描指定程序集中实现了IConsume 或 IConsumeAsync接口的类,然后这个自动订阅 ...
- iOS 自动订阅开发
一.代码逻辑 关于iOS 订阅.自动订阅 本身功能开发很简单.跟正常的购买没什么大的差异.唯一需要特殊处理(自动订阅)的是, 在APP启动时候要增加侦听: [[SKPaymentQueue defau ...
- 【EasyNetQ】- 自动订阅者
从v0.7.1.30开始,EasyNetQ简单易用AutoSubscriber.你可以用它来轻松地扫描实现任何接口的类的特定组件IConsume<T>或IConsumeAsync<T ...
- 【EasyNetQ】- 订阅
EasyNetQ订阅者订阅消息类型(消息类的.NET类型).一旦通过调用Subscribe方法设置了对类型的订阅,就会在RabbitMQ代理上创建一个持久队列,并且该类型的任何消息都将被放置在队列中. ...
- ThinkPHP3.1快速入门(12)自动验证
自动验证是ThinkPHP模型层提供的一种数据验证方法,可以在使用create创建数据对象的时候自动进行数据验证. 验证规则 数据验证可以进行数据类型.业务规则.安全判断等方面的验证操作.数据验证有两 ...
- easynetq发布订阅demo实现注意事项
最近开始在项目中使用easynetq,大概了解了下api,在网上看了下示例,结果没有一个运行成功的,一个最简单的发布订阅都没有成功.我是直接运行起来别人的示例,不应该啊,后来一直分析一直分析,最后发现 ...
- EMQ ---客户端上线自动订阅主题
通过修改配置文件即可实现. emq v2.3.11,软件架构做了调整,把功能集成在了emq_modules模块,/data/loaded_plugins默认会加载emq_modules. 我们只需要改 ...
- EasyNetQ使用(九)【非泛型的发布&订阅扩展方法,发生错误的情况 】
自从EasyNetQ第一个版本开始,它就可以发布/订阅特定类型的消息. bus.Subscribe<MyMessage>("subscriptionId", x =&g ...
随机推荐
- 2017-2018-2 165X 『Java程序设计』课程每周成绩公布
2017-2018-2 165X 『Java程序设计』课程 每周成绩公布 本博客将跟随教学进度不定期更新,每次更新后将在课程群公布.如对成绩有疑问,请于公布成绩后的1天之内联系助教,进行审核确认. - ...
- Java将list数据导出到Excel——(八)
Java实体类 package bean; public class Question { private String timu; //题干 private String leixing; //类型 ...
- Maven整合Spring3.0+Mybatis3.2+Struts2.3+查找坐标+jar包依赖(五)
依赖传递 只添加了一个struts2-core依赖,发现项目中出现了很多jar,这种情况 叫 依赖传递
- Python算法:推导、递归和规约
Python算法:推导.递归和规约 注:本节中我给定下面三个重要词汇的中文翻译分别是:Induction(推导).Recursion(递归)和Reduction(规约) 本节主要介绍算法设计的三个核心 ...
- UML和模式应用3:迭代和进化式分析和设计案例研究
1.前言 如何进行迭代和进化式分析和设计?将采用案例研究的方式贯穿始终.案例研究所包含的内容: UI元素 核心应用逻辑层 数据库访问 与外部软硬构件的协作 本章关于OOA/D主要介绍核心应用逻辑层 2 ...
- How to scroll down with Phantomjs to load dynamic content
page.open('http://example.com/?q=houston', function () { // Checks for bottom div and scrolls down f ...
- centos6下的lvm逻辑卷的管理
LVM:Logical Volume Manager 将多块设备组合成一个来使用 dm:device mapper 设备映射 设备文件 /dev/卷组名/逻辑卷名 /dev/mapp ...
- flask的orm框架(SQLAlchemy)-一对多查询以及多对多查询
一对多,多对多是什么? 一对多.例如,班级与学生,一个班级对应多个学生,或者多个学生对应一个班级. 多对多.例如,学生与课程,可以有多个学生修同一门课,同时,一门课也有很多学生. 一对多查询 如果一个 ...
- 【ES】学习5-全文搜索
全文搜索两个最重要的方面是:相关性, 分析. 一旦谈论相关性或分析这两个方面的问题时,我们所处的语境是关于查询的而不是过滤. match:单个词查询 GET /my_index/my_type/_se ...
- cf276E 两棵线段树分别维护dfs序和bfs序,好题回头再做
搞了一晚上,错了,以后回头再来看 /* 对于每次更新,先处理其儿子方向,再处理其父亲方向 处理父亲方向时无法达到根,那么直接更新 如果能达到根,那么到兄弟链中去更新,使用bfs序 最后,查询结点v的结 ...