• 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(10)
    };
    subscriber.Subscribe(Assembly.GetExecutingAssembly());

    或者,您可以将一个属性应用于使用方法,该方法优先于ConfigureSubscriptionConfiguration操作设置的任何配置值。

    public class MyConsumer : IConsume<MessageA>
    {
        [SubscriptionConfiguration(CancelOnHaFailover = true, PrefetchCount = 10)]
        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);

    现在,每次收到消息时,我们的消费者的新实例都将从我们的容器中解析出来。

  • 相关阅读:
    [原创]java WEB学习笔记26:MVC案例完整实践(part 7)---修改的设计和实现
    [原创]java WEB学习笔记25:MVC案例完整实践(part 6)---新增操作的设计与实现
    [原创]java WEB学习笔记24:MVC案例完整实践(part 5)---删除操作的设计与实现
    [原创]java WEB学习笔记23:MVC案例完整实践(part 4)---模糊查询的设计与实现
    Tapestry IoC Configuration
    Tapestry IoC Decorator
    Tapestry IoC Service
    Tapestry-Again
    mysql error nr.1045 解决方法
    Bootstrap学习 导航
  • 原文地址:https://www.cnblogs.com/zd1994/p/8651552.html
Copyright © 2020-2023  润新知