【EasyNetQ】- 自动订阅者
从v0.7.1.30开始,EasyNetQ简单易用AutoSubscriber
。你可以用它来轻松地扫描实现任何接口的类的特定组件IConsume<T>
或IConsumeAsync<T>
,然后让汽车用户订阅这些消费者到你的总线。一个实现IConsume<T>
将使用总线订阅方法,而实现IConsumeAsync<T>
将使用总线SubscribeAsync方法,请参阅订阅详细信息。您当然可以让您的消费者处理多条消息。我们来看看一些样品。
注意:从版本0.13.0开始,所有AutoSubscriber类都在EasyNetQ.AutoSubscribe命名空间中,因此请添加以下using语句:
using EasyNetQ.AutoSubscribe;
让我们定义一个简单的消费,处理三个消息:MessageA
,MessageB
和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前缀以所有自动生成的subscriptionId为前缀,但不以自定义subscriptionIds为前缀(见下文)。
要在同一个程序集中注册它和所有其他使用者,我们只需要将包含您的使用者的程序集传递给:AutoSubscriber.Subscribe(assembly)
。注意!这是你唯一应该做的ONCE,最好在应用程序启动。
var subscriber = new AutoSubscriber(bus, "my_applications_subscriptionId_prefix");
subscriber.Subscribe(Assembly.GetExecutingAssembly());
按主题订阅
默认情况下,AutoSubscriber
将绑定没有主题。在下面的示例中,MessageA注册了两个主题。
注意!如果您运行没有ForTopic属性的代码,它将具有“#”的路由键,它将获取对消息类型的任何订阅。假设安装了默认端口和管理插件,只需访问http//localhost:15672 /#/ queues并解除绑定路由(如果需要)。
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
指定特定的SubscriptionId
默认情况下,AutoSubscriber
将为SubscriptionId
每个消息/消费者组合生成唯一。这意味着您将启动同一个使用者的多个实例,并且它们将以循环方式(工作模式)从相同的队列中读取。
如果你想修改订阅ID,你可以Consume
用AutoSubscriberConsumerAttribute
。修饰方法。为什么要修复它,你可以在这里阅读。
可以说,上面的消费者应该有一个固定SubscriptionId
的消费方法MessageB
。只是装饰它并定义一个值SubscriptionId
。
[AutoSubscriberConsumer(SubscriptionId = "MyExplicitId")]
public void Consume(MessageB message) { }
控制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
价值的重要性。
控制消费者配置设置
使用autosubscriber订阅队列时,您可以设置ISubscriptionConfiguration值,例如AutoDelete,Priority等。
通过在创建AutoSubscriber时设置操作。
var subscriber = new AutoSubscriber(bus)
{
ConfigureSubscriptionConfiguration = c => c.WithAutoDelete()
.WithPriority()
};
subscriber.Subscribe(Assembly.GetExecutingAssembly());
或者,您可以将一个属性应用于consume方法,该方法优先于ConfigureSubscriptionConfiguration操作设置的任何配置值。
public class MyConsumer : IConsume<MessageA>
{
[SubscriptionConfiguration(CancelOnHaFailover = true, PrefetchCount = )]
public void Consume(MessageA message) {...}
}
在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);
现在,每当消息到达时,我们的消费者的新实例将从我们的容器中解析。
【EasyNetQ】- 自动订阅者的更多相关文章
- EasyNetQ使用(八)【对延迟消息插件的支持,自动订阅者】
RabbitMQ延迟消息插件仍然在实验阶段.你使用这个功能要自担风险. RabbitMQ延迟消息插件为RabbitMQ增加了新的交换机类型,允许延时消息投递. EasyNetQ为交换机通过定义一种新的 ...
- 16-EasyNetQ之自动订阅者
EasyNetQ v0.7.1.30版本有了一个简单AutoSubscriber.你能够使用它很容易的去扫描指定程序集中实现了IConsume 或 IConsumeAsync接口的类,然后这个自动订阅 ...
- iOS 自动订阅开发
一.代码逻辑 关于iOS 订阅.自动订阅 本身功能开发很简单.跟正常的购买没什么大的差异.唯一需要特殊处理(自动订阅)的是, 在APP启动时候要增加侦听: [[SKPaymentQueue defau ...
- 【EasyNetQ】- 订阅
EasyNetQ订阅者订阅消息类型(消息类的.NET类型).一旦通过调用Subscribe方法设置了对类型的订阅,就会在RabbitMQ代理上创建一个持久队列,并且该类型的任何消息都将被放置在队列中. ...
- easynetq发布订阅demo实现注意事项
最近开始在项目中使用easynetq,大概了解了下api,在网上看了下示例,结果没有一个运行成功的,一个最简单的发布订阅都没有成功.我是直接运行起来别人的示例,不应该啊,后来一直分析一直分析,最后发现 ...
- EMQ ---客户端上线自动订阅主题
通过修改配置文件即可实现. emq v2.3.11,软件架构做了调整,把功能集成在了emq_modules模块,/data/loaded_plugins默认会加载emq_modules. 我们只需要改 ...
- EasyNetQ使用(九)【非泛型的发布&订阅扩展方法,发生错误的情况 】
自从EasyNetQ第一个版本开始,它就可以发布/订阅特定类型的消息. bus.Subscribe<MyMessage>("subscriptionId", x =&g ...
- 【框架学习与探究之消息队列--EasyNetQ(2)】
声明 本文欢迎转载,系博主原创,本文原始链接地址:http://www.cnblogs.com/DjlNet/p/7654902.html 前言 此文章,是承接上篇:[框架学习与探究之消息队列--Ea ...
- .net core使用EasyNetQ做EventBus
随着SOA.微服务.CQRS的盛行,EventBus越来越流行,上GitHub搜了一下,还是有蛮多的这类实现,老牌的有NServiceBus(收费).MassTransit,最近的有CAP(国人写的, ...
随机推荐
- 『ACM C++』 PTA 天梯赛练习集L1 | 012-015
女神节快乐鸭,大学的女生节真的是忙碌呢,到处送礼物,真的是当时男生节的出来混的,总该是要还的hhhhh ------------------------------------------------ ...
- 02 shell编程之条件语句
Shell编程之条件语句 学习目标: 掌握shell脚本条件测试 掌握if语句编程 目录结构: 条件测试 条件测试概述 l 对特定的条件进行判断,以决定如何执行操作 l 测试的方法 方法1:tes ...
- kali下添加用户和权限分配
1.添加用户 useradd -m test #-m的意思是创建用户的主目录 2.为用户test设置密码. passwd test 3.为添加的用户赋予权限(-a 添加 :-G 群组) 如果没有这一步 ...
- 前端pc版的简单适配
我们都知道对于前端pc版本的适配是一个难题,大部分都是做的媒体查询.但是有时间公司不要媒体查询 就是需要不管多大的屏幕都是满屏显示.我就在考虑为啥不用rem给pc端做个适配. 我是基于设计图是1920 ...
- Python基本数据类型(一)
我会持续更新.... 字符串类型 字符串定义: 字符串的格式:'字符串', "字符串", """字符串"""字符串一旦被 ...
- Verilog学习笔记基本语法篇(七)········ 生成块
生成块可以动态的生成Verilog代码.可以用于对矢量中的多个位进行重复操作.多个模块的实例引用的重复操作.根据参数确定程序中是否包含某段代码.生成语句可以控制变量的声明.任务和函数的调用.还能对实例 ...
- springboot升级到2.x需要改动的地方
由于需要跟进技术发展的脚步,对原有项目springboot进行2.0升级,但升级并不是说改一下版本就完事了,springboot2.0变动比较多,详细变化可以百度一下,下面针对升级springboot ...
- Android面试收集录 网络与加密
1.创建Socket对象需要至少指定哪些信息? IP(或域名)和端口号 Socket socket=new Socket("www.baidu.com",80); 2.如何使用So ...
- Windows 10 下如何彻底关闭 Hyper-V 服务(翻外篇)
原文:Windows 10 下如何彻底关闭 Hyper-V 服务(翻外篇) windows禁用/启用hyper-V,解决hyper-V与模拟器同时启用时造成冲突 我是这样解决的,以管理员身份运行命令提 ...
- P1794 装备运输_NOI导刊2010提高(04)
P1794 装备运输_NOI导刊2010提高(04) 题目描述 德国放松对英国的进攻后,把矛头指向了东边——苏联.1943年初,东线的战斗进行到白热化阶段.据可靠情报,90余万德国军队在库尔斯克准备发 ...