A question I often meet in relation to messaging frameworks like NServiceBus and Rebus, is this: Where do messages go?
The confusion often comes from comparing how
bus.Publish works with how
bus.Send works.
In this post, I’d like to describe the two operations and show that they are mirror images of each other – except maybe not as much a mirror image as a transposition.
Sending messages
In the case where you’re doing a
bus.Send(message), the answer is trivial: The message gets sent to the endpoint specified in the sender’s enpoint mapping for that message type. Let’s say our sender is equipped with this snippet of XML[1. The snippet is an endpoint mapping in NServiceBus format, which can also be understood by Rebus when it’s running with the
DetermineDestinationFromNServiceBusEndpointMappings implementation of
IDetermineDestination] in its app.config:
|
<UnicastBusConfig> <MessageEndpointMappings> <add Messages="MyService.Messages" Endpoint="my_service"/> </MessageEndpointMappings> </UnicastBusConfig> |
If we assume that
message is an instance of a class from the
MyService.Messages assembly, in this case a
bus.Send(message) will be translated into
bus.Send("my_service", message).
Publishing messages
But where do messages go when they’re published? Well, they go to whomever subscribed to that particular message type – and with NServiceBus (and, for that matter, with Rebus as well) subscribers get subscribed by sending some kind of subscription message, which is basically saying: “Hey there, mr. Publisher – I’m
some_subscriber, and I’d like to subscribe to
MyService.Messages.SomeParticularMessage”.
From this point on, the publisher will store the mapping of the message type along with the subscriber’s address, allowing a
bus.Publish(message) method to be implemented something along the lines of
|
public void Publish(object message) { foreach(var subscriberEndpoint in GetSubscribersFor(message.GetType())) { Send(subscriberEndpoint, message); } } |
So – how do we understand this on a higher level, allowing us to never ever confuse these things again? Let’s dive into…
The duality
Consider these two sequence-like diagrams:
See how request/reply and publish/subscribe are actually the same patterns? The reason these two are often confused, is that the
Send operation is often countered by
Publish, when in fact it would be more fitting to see the subscription message (i.e. subscription request) as the counterpart of
Send. Thus,
Publishing is more like replying. And thus,
Send is actually the transposition of
Publish.
Now, when you realize this, you’re never going to confuse these things again 🙂 In the next post, I’ll touch a little bit on another difference between
Send and
Publish.