The subscription ID that you pass to subscribe is important
EasyNetQ will create a unique queue on the RabbitMQ broker for each unique combination of message type and subscription ID. Each call to Subscribe creates a new queue consumer. If you call the Subscribe
method two times with the same message type and subscription ID, you will create two consumers consuming from the same queue. RabbitMQ will then round-robin successive messages to each consumer in turn. This is great for scaling and work-sharing. Say you've created a service that processes a particular message, but it's getting overloaded with work. Simply start a new instance of that service (on the same machine, or a different one) and without having to configure anything, you get automatic scaling.
If you call the Subscribe
method two times with different subscription IDs but the same message type, you will create two queues, each with its own consumer. A copy of each message of the given type will be routed to each queue, so each consumer will get all the messages (of that type). This is great if you've got several different services that all care about the same message type.
Considerations when writing the subscribe callback delegate
As messages are received from queues subscribed to via EasyNetQ, they are placed on an in-memory queue. A single thread sits in a loop taking messages from the queue and calling their action delegates. Since the delegates are processed one at a time on a single thread, you should avoid long-running synchronous IO operations. Return control from the delegate as soon as possible.
Using SubscribeAsync
SubscribeAsync
allows your subscriber delegate to return a Task
immediately and then asynchronously execute long-running IO operations. Once the long-running subscription is complete, simply complete the Task
.
Canceling subscriptions
All the subscribe methods return an ISubscriptionResult
. It contains properties that describe the IExchange
and IQueue
used by the underlying IConsumer
; these can be further manipulated using the advanced API IAdvancedBus
if required.
You can cancel a subscriber at any time by calling Dispose
on the ISubscriptionResult
instance or on its ConsumerCancellation
property:
var subscriptionResult = bus.Subscribe<MyMessage>("sub_id", MyHandler); subscriptionResult.Dispose();
This will stop EasyNetQ consuming from the queue and close the consumer's channel. It is the equivalent to calling subscriptionResult.ConsumerCancellation.Dispose()
;
Note that disposing of the IBus
or IAdvancedBus
instance will also cancel all consumers and close the connection to RabbitMQ.