4
votes

I am not able to figure out on how to specify the Exchange and Queue in my GetSendEndpoint()) task when sending / publishing messages?

As per MassTransit documentation https://masstransit-project.com/usage/producers.html#send you can specify the exchange and queue like

GetSendEndpoint(new Uri("queue:input-queue"))

However, I can only do one or the other?

Is there an alternative way of sending with exchange and queue specified?

I am doing this in Asp.Net Core so here are my configuration:

Startup.cs

public void ConfigureServices(IServiceCollection services)
{
   services.AddMassTransit();

   services.AddSingleton(p => Bus.Factory.CreateUsingRabbitMq(cfg =>
   {
         cfg.Host("rabbitmq://localhost", h =>
         {
             h.Username("admin");
             h.Password("admin");
         });
   }));

   services.AddSingleton<IBus>(p => p.GetRequiredService<IBusControl>());
   services.AddSingleton<IHostedService, BusService>();
}

And this is how send the message

var endpoint = await _bus.GetSendEndpoint(new Uri(queue:Test.Queue));
await endpoint.Send(new Message()
{
     Text = "This is a test message"
});

As you can see I can only specify the queue name.

2

2 Answers

6
votes

If you specify an exchange, only the exchange is declared on the broker. The message will be sent directly to the exchange.

"exchange:your-exchange-name"

If you specify a queue, the queue along with an exchange of the same name will be declared and the exchange will be bound to the queue. Messages will be delivered to the exchange of the same name, which will deliver them to the queue.

"queue:your-queue-name"

If you want a different exchange and queue name, you can specify both using:

"exchange:your-exchange-name?bind=true&queue=your-queue-name"

Or you could simplify, but it's a little confusing with two queues:

"queue:your-exchange-name&queue=your-queue-name"
4
votes

Reading Chris's response in here Mass Transit : No consumer

It seems like Exchanges are created by MassTransit when publishing messages, based on the message types. Publishing does not create any queues. Queues are where messages are stored for delivery to consumers.

and Queues are created when receive endpoints are added to a bus. For the consumers, handlers, and sagas added to a receive endpoint, the exchanges are created and bound so that messages published to the exchanges are received by the receive endpoint (via the queue).

So if my publisher doesn't have a receive endpoint defined then any messages I send will be lost as there will be no queues or binding?

Further reading on here https://groups.google.com/forum/#!topic/masstransit-discuss/oVzZkg1os9o seems to further confirm this.

So based on the above link in order to achieve what I want i.e. to create the exchange and bind it to a queue I will need to specify it in the Uri as such

var sendEndpoint = bus.GetSendEndpoint(new Uri("rabbitmq://localhost/vhost1/exchange1?bind=true&queue=queue1"));

where exchange1 is the Exchange, queue1 is the Queue and bind=true would bind the queue to the exchange.

If sticking to the original MT design a Consumers needs to be running before to setup the exchanges and queues before a Producer can start publishing? This seems to give less flexibility to the Publisher?