Messaging Patterns with Postal.NET

Introduction

Some of you may remember Postal.NET from my previous posts (here, here and here). In a nutshell, it is a framework I built for writing decoupled applications in .NET, in a publish-subscribe way. It is available as open source in GitHub (do have a look at the README file) and available in Nuget.

I recently added request-response synchronous support. This is so that two parties, without knowing exactly who they are, can engage in a direct conversation. Other enterprise buses support this feature as well.

So, with that in mind, let’s recap all of the messaging patterns we have in Postal.NET. Remember that at least you need to grab the Postal.NET Nuget package.

Publish-Subscribe

OK, this is easy: someone subscribes to a channel-topic pair and someone else publishes a message to it, either synchronously or asynchronously:

//subscriber

var subscription = Postal.Box.Subscribe("some channel", "some topic", (env) => ProcessMessage(env));

 

//synchronous publisher

Postal.Box.Publish("some channel", "some topic", someMessage);

 

//asynchronous publisher

await Postal.Box.PublishAsync("some channel", "some topic", someMessage);

It is also possible to subscribe to all messages and equally to broadcast to all channels and topics:

//subscribe to all channels and topics

var broadcastSubscription = Postal.Box.Subscribe("*", "*", (env) => ProcessAllMessages(env));

 

//broadcast to all channels and topics

await Postal.Box.PublishAsync("*", "*", shutdownMessage);

Finally, it is possible to conditionally process a message:

var filteredSubscription = Postal.Box.Subscribe("some channel", "some topic", (env) => ProcessMessage(env), (env) => env.Data is string);

Publish-Subscribe to Multiple Channels

Another option is to subscribe to multiple channel/topic pairs at the same time:

var combinedSubscription = Postal.Box.SubscribeMultiple("some channel", "a topic, another topic", (env) => ProcessMessage(env));

Here, an event will be raised if a message is published to any of the given topics, separated by commas.

Likewise, it is also possible to publish at the same time to several channels:

await Postal.Box.PublishAsync("a channel", "a topic, another topic", someMessage);

When the subscription is cancelled, it will cancel all channel/topic pairs at the same time.

Handle a Single Event

You can subscribe to an event only once and terminate the subscription as soon as you receive it, no need (or possible) to cancel it:

Postal.Box.Once("a channel", "a topic", (env) => ProcessMessage(env));

Event Composition

Yet another option is to use composition: do something only after this and that event has occurred. You need to install first the PostalWhen.NET package.

var composedSubscription = Postal

    .Box

    .When("a channel", "a topic")

    .And("a channel", "another topic", (env) => ShouldProcess(env))

    .Subscribe(env => ProcessSaga(env));

Reactive Subscriptions

Postal.NET plugs in nicely with Reactive Extensions, including all of its goodies, like buffering. Get PostalRX.NET:

var observable = Postal.Box.Observe("a channel", "a topic");

 

//groups 5 messages

var bufferedSubscription = observable

    .Buffer(5)

    //msgs is a collection of 5 envelopes

    .Subscribe((msgs) => ProcessBufferedMessage(msgs), (ex) => ProcessException(ex), () => ProcessTermination());

Request-Response

The last pattern added was request-response. With it, you can reply synchronously to the requestor, each without knowing about the other. The code for this lives in Nuget as PostalRequestResponse.NET:

var subscription = Postal.Box.Subscribe("a channel", "a topic", (env) =>

    {

        //check if it is a request-response message

        if (env.IsRequestResponse() == true)

        {

            //extract the contents from it

            var someMessage = env.Unwrap<SomeMessage>();

            Postal.Box.Reply(env, GetResponse(someMessage));

        }

    });

 

//Gets the results from GetResponse synchronously

var response = Postal.Box.Request("a channel", "a topic", someMessage);

Conclusion

You can see that Postal.NET offers some interesting patterns which hopefully cover most use cases. If you want to know more, do check out GitHub or drop me a note!

Published by

Ricardo Peres

Team Leader at Dixons Carphone. Microsoft MVP.

Leave a Reply

Your email address will not be published. Required fields are marked *