In an environment where multiple high transaction server applications need to communicate with each other, finding the best communication channel for them is important.
A publisher/subscribe model is one of the most popular ways when it comes to providing a communication platform for your applications. We all know what these mediums have in common; multiple clients publish messages and multiple clients can subscribe to them. This all happens in an extremely decoupled manner, meaning that the publisher does not deploy the messages directly to the subscribing clients. Instead, a message bus is used as an intermediary channel through which all clients communicate.
In short, pub/sub messaging is a method where neither the publisher nor the subscriber knows anything about each other’s identity.
Let’s take a moment here to think about what happens when the number of publishers and subscribers increases. The greater this number is, the greater the messaging load is going to be. This situation leads to your Pub/Sub platform inducing scalability bottlenecks, which defeats the main purpose of introducing a decoupled messaging interface.
Let us look at a solution that not only inherits the general working of pub/sub but also adds a bunch of other functionalities to it for your ease; a method that is fast and extremely scalable.
Using NCache In-Memory Pub/Sub
NCache provides you with fast, flexible, most linearly scalable distributed caches for your .NET application.
Using NCache as your event-driven Pub/Sub platform can prove extremely beneficial if you plan on scaling your application on the go. It prevents any bottlenecks from occurring in your system.
Here’s how NCache acts as a messaging bus for your application:
NCache acts as an intermediary interface for your Pub/Sub implementation. The figure illustrates that not only one but multiple clients can subscribe to one or multiple topics at a time.
Any number of applications can connect to the cache and start publishing messages on the NCache servers. These messages are then subscribed to by various clients according to their requirements. Through NCache, you get to decide whether all or just one subscriber gets to receive the messages published. By doing so, NCache acts as a messaging bus for your .NET server applications.
Quick Pub/Sub Example with NCache
Let’s assume that I have an online gaming application that is being used by players all around the world. In my application, I have a feature that incorporates not only audio comms but also runtime messages. Multiple players send messages against a channel and for their own team players at the same time.
Considering the number of players playing the game, the message load is going to be huge. What I need here is a communication interface that boosts my game’s performance. And for this, I prefer NCache as my game’s message bus.
Following is the snippet that I use to implement a scenario where server applications can publish and receive messages. This code shows how you get a topic and publish a message against it.
// Precondition: Cache is already connected // Get the topic ITopic teamChat = cache.MessagingService.GetTopic("RuntimePlayerComms"); // Create the object to be sent in message // Get information of the player through player ID Player teamLeader = FetchInfo(1); // Create the message var newChatMessage = new Message(teamLeader); // Set the expiration time of the message newChatMessage.ExpirationTime = TimeSpan.FromSeconds(60); // Publish the message with delivery option set to All subscribers teamChat.Publish(newChatMessage, DeliveryOption.All, true);
Once a message has been published against a topic, the subscribers create subscriptions against that topic to receive messages. The following code demonstrates how subscribing applications subscribe to a certain topic to receive desired messages.
// Precondition: Cache is already connected // Get the topic ITopic teamChat = cache.MessagingService.GetTopic("RuntimePlayerComms"); // Create and register subscribers for the topic // MessageReceived is the callback through which the message is delivered ITopicSubscription subscriber = teamChat.CreateSubscription(MessageReceived);
Till now, all I talked about was the general working of pub/sub but what you really need to know is the extra lengths that NCache goes to just to meet your needs.
Are you wondering what those “other functionalities” that I previously exclaimed are? Let us get right to the features exclusively offered by NCache.
Pub/Sub Exclusive Durable Subscriptions
Normally, when a client subscribes to a topic, that subscription is known as a non-durable subscription, meaning that if the client disconnects from the server, all of its subscriptions are lost.
NCache provides you with durable subscriptions. In this case, even if the connection between the server and the client breaks, all of that client’s subscriptions remain intact. So, when the client is reconnected, it receives all the messages that were published while the subscriber was disconnected.
The way you execute this scenario in your application is simple. You add the following line of code in your application to implement an exclusive durable subscription.
// Create and register subscribers for the topic // MessageReceived callback is specified // The subscription policy is Exclusive IDurableTopicSubscription subscriber = teamChat.CreateDurableSubscription("RuntimePlayerComms", SubscriptionPolicy.Exclusive, MessageReceived, TimeSpan.FromMinutes(20));
As long as the connection is alive, no new client can subscribe to that subscription. If this connection breaks, the messages are kept and when the connection is reestablished, they are sent to the client. This is done so that no message is lost.
Pub/Sub Shared Durable Subscriptions
Apart from exclusive subscriptions, durability can also be achieved through shared subscriptions. In this type of subscription, more than one client can subscribe to a single subscription. This serves the purpose of load sharing.
Shared subscriptions use the Round Robin method to send messages to all connected clients. So, even if a client is disconnected, the messages continue to be distributed among the remaining subscribers.
A subscription stays active for as long as there is even a single client connected to it. Following code is how my online gaming application implements shared durable subscriptions.
// Create and register subscribers for the topic // MessageReceived callback is specified // The subscription policy is Shared IDurableTopicSubscription subscriber = teamChat.CreateDurableSubscription("RuntimePlayerComms", SubscriptionPolicy.Shared, MessageReceived, TimeSpan.FromMinutes(20));
By default, these subscriptions are exclusive that allow exactly one subscriber per subscription.
Pub/Sub Pattern Based Subscriptions
Sometimes, instead of subscribing to named subscriptions one by one, a pattern is provided under which all the topics, present and to come, are subscribed in one go. To accommodate this, NCache facilitates its clients by providing pattern-based subscriptions. Through this method, a topic or multiple topics that fall under the pattern provided can be subscribed easily.
To know the kinds of wildcards supported by NCache’s pattern-based subscriptions, please refer to NCache documentation on Pattern-Based Subscriptions.
Following is an example snippet of how I use pattern-based wildcards in my gaming application.
// Only ? *  wildcards supported string topicName = "team*"; string subscriptionName = "TeamPlayersComms"; // Get the topic ITopic teamChat = cache.MessagingService.GetTopic(topicName, TopicSearchOptions.ByPattern);
Why NCache for Pub/Sub?
Why favor NCache, you might ask? Well… NCache is
- fast because it’s an in-memory solution.
- linearly scalable because you can add additional servers at runtime; any time.
- flexible as it dynamically auto rebalances data without any client intervention.
The way I see it, NCache provides the best, most scalable and the fastest way to accommodate message communication within your application. The fact that NCache is an in-memory, distributed caching solution is enough to counter any bottlenecks that might arise due to message load. Now, this is the win-win situation you need in your .NET application.