Pub/Sub In Node.js Apps Using Azure Service Bus Topics

In my previous post Building Distributed Node.js Apps with Azure Service Bus Queue, we have discussed how we can design distributed apps in Node.js by leveraging Microsoft Azure Service Bus Queues. Service Bus Queue provides brokered communication between apps regardless of whether hosted on Cloud or on-premises server. Service Bus Queue is designed for delivering the brokered messages to single consumer or an app. We can say that Service Bus Queue is providing a one-to-one communication infrastructure. But, in many scenarios, we may need to deliver the brokered messages to multiple consumers or apps, where we can use Azure Service Bus Topics and Subscriptions which provides a one-to-many communication with a publish/subscribe pattern. Service Bus Topics are built on the top of Service Bus Queues for working with publish/subscribe scenarios. In this post, I will take a look at Azure Service Bus Topics and Subscriptions for implementing publish/subscribe pattern in Node.js apps.

Create Azure Service Bus Topics For Publishing Messages to Subscribers

In order to working with Azure Service Bus, we need to create a Service Bus namespace from Azure portal. if you need a free trial account in Azure, you can get it from here. Let’s create a Service Bus Topics to be consumed for subscribers of our distributed application.

Creating Azure Service Bus Client

Firstly, we need to install npm module azure to working with Azure services from Node.js app.

npm install azure

The code block below creates a Service Bus client object using the Node.js module azure.

var azure = require('azure');
var config=require('./config');
var serviceBusClient = azure.createServiceBusService(
                   config.sbConnection);

We create the Service Bus client object by using createServiceBusService method of azure module. In the above code block, we pass the Service Bus connection string from a config file. The azure module can also read the environment variables AZURE_SERVICEBUS_NAMESPACE and AZURE_SERVICEBUS_ACCESS_KEY for information required to connect with Azure Service Bus where we can call  createServiceBusService method without specifying the connection information. We can set the environment variables for our Node.js app in the Azure developer portal for Azure Website and Azure Cloud Services apps.

Create Azure Service Bus Topic

In the previous step, we have created the Service Bus client object. Let’s create a Topics for publishing messages for its subscribers. The createTopicIfNotExists method of Service Bus client object, will create a new Topic or returns an existing Topic.

var topic = 'orders';
function createTopic() {
    //Create topic
    serviceBusClient.createTopicIfNotExists(topic, 
function (error) {
        if(!error){
            console.log('Topic created or exists.');
        }
    });
}

The figure below shows that we have created Topic with name “orders”.

image

Create Azure Service Bus Subscriptions For Topics

Azure Service Bus Subscriptions can subscribe the messages published by Azure Service Bus Topics. In order to subscribe the messages published by the Topics, we have to create Subscriptions for the Topics. We can create Azure Service Bus Subscriptions by using createSubscription method of Service Bus client object.

function createSubscription(subscriber) {
// Create subscription
serviceBusClient.createSubscription(topic, subscriber,
 function (error) {
        if (error) {
            console.log(error);
        }
        else
        {
            console.log('Subscriber '+ subscriber+ ' 
              registered for '+ topic+ ' messages');
        }
    });
}

Typically, these subscribers will be different apps in a distributed app environment. Let’s create couple of subscribers for the sake of the demo.

var subscription1 = 'supplier1';
var subscription2 = 'supplier2';
 
createSubscription(subscription1);
createSubscription(subscription2);

The figure below shows that two subscriptions registered in the Azure portal for the Topics “orders”

image

Publishing Messages from Azure Service Bus Topic Messages

Let’s create Topic messages to later be consumed from subscriber apps.

function sendMessage(message) {
    // Send messages for subscribers
    serviceBusClient.sendTopicMessage(topic, message, 
   function(error) {
        if (error) {
            console.log(error);
        }
        else {
            console.log('Message sent');
        }
    });
}

Let’s send couple of Topic messages

var orderMessage1={"OrderId":101,
"OrderDate": new Date().toDateString()};
sendMessage(JSON.stringify(orderMessage1));
var orderMessage2={"OrderId":102,
"OrderDate": new Date().toDateString()};
sendMessage(JSON.stringify(orderMessage2));

Receiving Messages from Azure Service Bus Subscriptions

Subscriber apps can receive the message from Topics by using the method receiveSubscriptionMessage. The code block below reads the messages from Topics for two times. This will read the two messages we have published from Topics in the previous steps.

function receiveMessages(subscriber) {
    // Receive the messages for subscription.
    serviceBusClient.receiveSubscriptionMessage(topic, subscriber,
 function (error1, message1) {
        if (error1) {
            console.log(error1);
        } else {
            var topicMessage1 = JSON.parse(message1.body);
            console.log('Processing Order# ' + topicMessage1.OrderId
                + ' placed on ' + topicMessage1.OrderDate+ ' from ' + subscriber);
            //call for receive next message
            serviceBusClient.receiveSubscriptionMessage(topic, subscriber,
      function (error2, message2) {
                if (error2) {
                    console.log(error2);
                } else {
                    var topicMessage2 = JSON.parse(message2.body);
                    console.log('Processing Order# ' + topicMessage2.OrderId
                        + ' placed on ' + topicMessage1.OrderDate+ ' from ' + subscriber);
                }
            });
        }
    });
}

Unlike Service Bus Queues, which provides brokered messages for one app, Azure Service Bus Topics and Subscriptions can be used for subscribing messages for multiple apps. In the previous steps, we have created a Topic named “orders” where we have published two messages. We have registered two subscribers for subscribing the messages from Topics. Let’s call the method receiveMessages for our two subscribers.

receiveMessages(subscription1);
receiveMessages(subscription2);

The below console window shows that two messages published from the order Topics received from the two subscribers.

image

Source Code

The source code for the sample code, is available at https://github.com/shijuvar/azureservicebus-demos.

Scaling Socket.IO Apps with Azure Service Bus Topics

By leveraging the Azure Service Bus Topics, we can scale out Socket.io apps to multiple processes and multiple servers. Node.js module socket.io-servicebus can be used for scale out Socket.io apps, where Service Bus Topics are working as a store model for Socket.io. The Pub/Sub nature of Azure Service Bus Topics is ideal for working as a store model for Socket.IO. For more details, check out my blog post Scaling Node.js Real-time Apps with Windows Azure Service Bus 

You can follow me on twitter at @shijucv

 

 

 

 

No Comments