消息中间件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
{
x.UseRoutingKeyFormatter(context => RoutingKeyConvention(context.Message.RoutingKey));
});
cfg.Message
{
x.SetEntityName(ExchangeName);
});
//如下是我增加的,不然发不出消息,我使用的是Rabbit3.6,MassTransit 5.3.1,by dacong
cfg.Publish
});
busControl.Start();
var builder = new ContainerBuilder();
builder.RegisterType
var container = builder.Build();
var ctx = container.Resolve
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
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
});
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
{
private IComponentContext componentContext;
public MyConsumer(IComponentContext componentContext)
{
this.componentContext = componentContext;
}
public Task Consume(ConsumeContext
{
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}"路由到具体的队列中。