消息中间件masstransit使用routingkey进行自定义消息路由到队列

消息中间件masstransit使用routingkey进行自定义消息路由到队列,就是RabbitMQ按照主题Topic进行消息的路由分发。

参考:https://github.com/Danthar/masstransit-topic-sample

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Autofac;
using MassTransit;
using MassTransit.RabbitMqTransport;
using RabbitMQ.Client;

namespace testcase
{
    class Program
    {
        private static string _url = "rabbitmq://nlehvportalbeacc/ontwikkel-smits";
        private static string _user = "console";
        private static string _password = "console";
        
        private static IRabbitMqHost _host;
        private static string ExchangeName = $"testcase-ordered-buffer";

        static void Main(string[] args)
        {
            var busControl = Bus.Factory.CreateUsingRabbitMq(cfg =>
            {
                _host = cfg.Host(new Uri(_url), h =>
                {
                    h.Username(_user);
                    h.Password(_password);
                });
                cfg.Send<MyMessage>(x =>
                {
                    x.UseRoutingKeyFormatter(context => RoutingKeyConvention(context.Message.RoutingKey));
                });
                cfg.Message<MyMessage>(x =>
                {
                    x.SetEntityName(ExchangeName);
                });

//如下是我增加的,不然发不出消息,我使用的是Rabbit3.6,MassTransit 5.3.1,by dacong

cfg.Publish<MyMessage>(x=>x.ExchangeType=ExchangeType.Direct);
            });

            busControl.Start();

            var builder = new ContainerBuilder();
            builder.RegisterType<MyConsumer>();
            var container = builder.Build();

            var ctx = container.Resolve<IComponentContext>();

            Subscribe(ctx, "foo");
            Subscribe(ctx, "bar");
            var input = "";
            do
            {
                Console.WriteLine("ready");
                busControl.Publish(new MyMessage("Hello world", "foo"));
                busControl.Publish(new MyMessage("Hello world", "bar"));    
                input = Console.ReadLine();
            } while (input != "q");

            busControl.Stop();
        }

        static void Subscribe(IComponentContext context, string key)
        {
            var queuename = $"testcase-R-{key}";
            var handle = _host.ConnectReceiveEndpoint(queuename, e =>
            {
                e.BindMessageExchanges = false;
                e.Consumer<MyConsumer>(context); //<-- autofac is used to more closely represent the realworld scenario
                e.Bind(ExchangeName, x =>
                {
                    x.RoutingKey = RoutingKeyConvention(key);
                    x.ExchangeType = ExchangeType.Direct;
                    x.Durable = true;
                });
                //this and SetEntityName are mutually exclusive, causes vague exceptions if you do.
                //Turn this on, and SetEntityName off. And you do receive messages. But routingkey constraints
                //are not enforced. So each consumer receives all published messages. Instead of only the ones belonging to its topic
                //e.Bind<MyMessage>(); 
            });

            handle.Ready.ConfigureAwait(false).GetAwaiter().GetResult();
        }

        static string RoutingKeyConvention(string key)
        {
            Console.WriteLine("routing-convention queried");
            return $"some-prefix-{key}";
        }
    }

    public class MyMessage
    {
        public string RoutingKey { get; set; }

        public string Content { get; set; }

        public MyMessage(string content, string routingKey)
        {
            RoutingKey = routingKey;
            Content = content;
        }
    }

    public class MyConsumer : IConsumer<MyMessage>
    {
        private IComponentContext componentContext;
        public MyConsumer(IComponentContext componentContext)
        {
            this.componentContext = componentContext;
        }

        public Task Consume(ConsumeContext<MyMessage> context)
        {
            Console.WriteLine($"Received {context.Message.Content} for {context.Message.RoutingKey}");
            return Task.CompletedTask;
        }
    }
}
 

//消息参与Direct方式发到交换器testcase-ordered-buffer,使用此交换器发送到testcase-R-foo,testcase-R-bar,使用$"some-prefix-{key}"路由到具体的队列中。

发布了181 篇原创文章 · 获赞 35 · 访问量 76万+

猜你喜欢

转载自blog.csdn.net/dacong/article/details/92207470