Azure Service Bus Topic And Subscription (Pub-Sub)

Azure Service Bus Topic And Subscription (Pub-Sub)

Azure Service Bus - Topic

This articles explains about Azure Service Bus Topic and Subscription which is commonly known as pub-sub with a real world scenario.

Business Requirement

The business requirement is in my previous article,

Azure Service Bus - Working With Queue In A Real World Scenario

So far we have seen about mobile recharge where we have used queuing mechanism. Now a company wants to provide some offers on regular recharge. But how will registered users come to know about these offers?

So again the company has started looking for some solution and finally it has come up with the solution of Azure Service Bus - Topic. Topic works like pub-sub model where one is the publisher and there can be many subscribers for the same publisher. In our scenario the publisher will publish offers and subscribed users will get the offers immediately.

image.png

Now let's see the step by step implementation of the below to design a solution:

  • Log in to the Azure portal via portal.azure.com
  • Explore previously created Service Namespace; i.e. Mobile Recharge
  • Click on '+Topic' under Topics to create a new topic

image.png

  • Give appropriate name for Topic
  • Keep the rest of the input values as is and click on 'Create' button

image.png

We can see that Topic is created in it is shown under topics list.

image.png

  • Click on previously created topic; i.e. 'Offers', which will show the list of subscriptions. As of now it shows empty
  • Click on '+Subscription' under subscriptions to create subscription

image.png

  • Give proper name of subscription
  • Change Lock duration to 5 minutes and click on 'Create' button, which will create subscription for topic

image.png

  • Follow the preceding steps and create one more subscription

image.png

We can see both the subscriptions in the list.

image.png

Credentials Click on 'Shared access policies' from the left panel, click on 'RootManageSharedAccessKey' to explore keys and connection strings which will be used further to connect.

image.png

Publish Message

  • Create a console application in Visual Studio
  • Set variables, one for connection string which you can copy from Shared access policies section and another is topic name; i.e. offers
  • In order to publish the offers, we need an offer from user
  • Add Microsoft.Azure.ServiceBus from a NuGet package manager
  • Create topic client using connection string and queue name
  • Convert string message to Azure Service Bus message
  • Using topic client, call SendAsync method to publish the message.
  • Call CloseAsync to close opened connection in finally block.
 class Program  
        {  
            static ITopicClient topicClient;  
            static void Main(string[] args)  
            {  
                string sbConnectionString = "Endpoint=sb://mobilerecharge.servicebus.windows.net/;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=KVb9ubc9XaV0dT/1dMjW9CzPWvA/JGvVvUZ64U21IBI=";  
                string sbTopic = "offers";  

                string messageBody=string.Empty;  
                try  
                {  
                    Console.WriteLine("-------------------------------------------------------");  
                    Console.WriteLine("Publish Offer");  
                    Console.WriteLine("-------------------------------------------------------");  
                    Console.WriteLine("Offers");  
                    Console.WriteLine("1. Recharge with 100 and get talk time of 110");  
                    Console.WriteLine("2. Get 5 GB data on recharge of 300. Validity 28 days");  
                    Console.WriteLine("3. 1000 SMS in recharge of 100");  
                    Console.WriteLine("-------------------------------------------------------");  

                    Console.WriteLine("Offer:");  
                    string offer = Console.ReadLine();  

                    Console.WriteLine("-------------------------------------------------------");  

                    switch (offer)  
                    {  
                        case "1":  
                            offer = "Recharge with 100 and get talk time of 110";  
                            break;  
                        case "2":  
                            offer = "Get 5 GB data on recharge of 300. Validity 28 days";  
                            break;  
                        case "3":  
                            offer = "1000 SMS in recharge of 100";  
                            break;  
                        default:  
                            break;  
                    }  

                    messageBody = offer;  
                    topicClient = new TopicClient(sbConnectionString, sbTopic);  

                    var message = new Message(Encoding.UTF8.GetBytes(messageBody));  
                    Console.WriteLine($"Message Published: {messageBody}");  

                    topicClient.SendAsync(message);  

                }  
                catch (Exception ex)  
                {  
                    Console.WriteLine(ex.Message);  
                }  
                finally  
                {  
                    Console.ReadKey();  
                    topicClient.CloseAsync();  
                }  
            }  
        }
  • Run the application and select the offer which you would like to publish
  • You can see the published message 'Message Published…'

image.png

We can see that published message is added in all available subscriptions.

image.png

Read message from subscription

  • Create a console application in the Visual Studio
  • Set variables, one for connection string which you can copy from Shared access policies section and another is topic name; i.e. offers
  • Create topic client using connection string and queue name
  • Using topic client, call RegisterMessageHandler which is used to receive messages continuously from the entity. It registers a message handler and begins a new thread to receive messages. This handler is waited on every time a new message is received by the receiver.
  • Inside ReceiveMessageAsync, call CompleteAsync which completes a message using its lock token and deletes the message from the queue.
    class Program  
        {  
            static ISubscriptionClient subscriptionClient;  
            static void Main(string[] args)  
            {  
                string sbConnectionString = "Endpoint=sb://mobilerecharge.servicebus.windows.net/;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=KVb9ubc9XaV0dT/1dMjW9CzPWvA/JGvVvUZ64U21IBI=";  
                string sbTopic = "offers";  
                string sbSubscription = "akki5677";  
                try  
                {  
                    subscriptionClient = new SubscriptionClient(sbConnectionString, sbTopic, sbSubscription);  

                    var messageHandlerOptions = new MessageHandlerOptions(ExceptionReceivedHandler)  
                    {  
                        MaxConcurrentCalls = 1,  
                        AutoComplete = false  
                    };  
                    subscriptionClient.RegisterMessageHandler(ReceiveMessagesAsync, messageHandlerOptions);  
                }  
                catch (Exception ex)  
                {  
                    Console.WriteLine(ex.Message);  
                }  
                finally  
                {  
                    Console.ReadKey();  
                    subscriptionClient.CloseAsync();  
                }  
            }  

            static async Task ReceiveMessagesAsync(Message message, CancellationToken token)  
            {  
                Console.WriteLine($"Subscribed message: {Encoding.UTF8.GetString(message.Body)}");  

                await subscriptionClient.CompleteAsync(message.SystemProperties.LockToken);  
            }  

            static Task ExceptionReceivedHandler(ExceptionReceivedEventArgs exceptionReceivedEventArgs)  
            {  
                Console.WriteLine(exceptionReceivedEventArgs.Exception);  
                return Task.CompletedTask;  
            }  
        }
  • Run the application and you can see the previously added message in the subscription.

image.png

Now if you closely observe message count for all available subscriptions, one of the subscriptions has a zero message count as we have already read from that subscription and another subscription shows 1 as a message count means we need to publish once and it will be available for all subscriptions and whom so ever is read that only will be deleted and for rest it will be as it is.

image.png

  • Now run both the applications simultaneously and select the offer which you would like to publish
  • You can observe that the message will be read by the second application immediately.

image.png

Azure service bus topic is very similar to Azure service bus queue, the difference is queue works on one to one; i.e. one sender and one receiver whereas topic works on one to many; i.e. One publisher and many subscribers.

Note: Download complete sample code from here .