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:
1 2 3 4 5 |
<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
1 2 3 4 5 6 7 |
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.