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,
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.
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
- Give appropriate name for Topic
- Keep the rest of the input values as is and click on 'Create' button
We can see that Topic is created in it is shown under topics list.
- 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
- Give proper name of subscription
- Change Lock duration to 5 minutes and click on 'Create' button, which will create subscription for topic
- Follow the preceding steps and create one more subscription
We can see both the subscriptions in the list.
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.
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…'
We can see that published message is added in all available subscriptions.
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.
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.
- 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.
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.