Topics, Subscriptions and Receivers in Windows Azure App Fabric Service Bus

 

I believe the most complex thing I found when looking into the Azure AppFabic Service bus is the pricing model. After spending quite a few precious minutes of my life I now think understood it but I am still not sure if I am correct. So this matter has to wait until my next statement arrives and I got yelled by my support department. At which time I may come back with a blog on that. Meanwhile you can go ahead and have a look at the pricing FAQ at

http://www.microsoft.com/windowsazure/faq/#pricing

good luck with that Smile

So now back to simpler things, Usually Udi Dahan starts his NServiceBus presentation with this “Where is the bus, There is no bus”. Well in the case of AppFabric Service Bus there is a Bus. You can have a look at it at the Azure management portal.

Now I will use this bus to create a simple chat application and while I am using it I will try explain some of its concepts. Please make sure to install the relevant SDK installed from the following link

http://www.microsoft.com/download/en/details.aspx?displaylang=en&id=27421

Our chat application is a WPF application containing only one screen. The application allow any number of users to join in and every one will see every one’s messages. For simplicity the user names are given in the configuration file. So the main screen only has a list of messages, a message textbox and a send button. Application uses MVVM so most of our functionality resides in the ViewModel. I am using Galasoft’s MVVM light framework here which is a treat to use in it self but more on that later.

Long story short the button is bound to a command and we are mostly concerned from that point onwards.

image

I have encapsulated all the logic related to the service bus functionality into a separate class let us call it service bus manager in its constructor the class connects to the service bus and tries to create the initial structure required for the communication. Have a look at the following code

var tokenProvider =
           TokenProvider.CreateSharedSecretTokenProvider(IssuerName, IssuerKey);
           var serviceUri = ServiceBusEnvironment.CreateServiceUri("sb", ServiceNamespace, string.Empty);

           _namespaceManager = new NamespaceManager(serviceUri, tokenProvider);

The bold variables actually signify some steps that should be done before starting the code i.e. You should create a Service Name space. The service name space is actually the unique identity of your service using which your service bus will be located. Here is a link on how you can do it otherwise you can log into the Azure Management portal and find your way to do that,

http://debugmode.net/2011/04/05/getting-started-with-azure-appfabric-service-bus-creating-namespace/

Once your namespace is created and selected you will be able to see Default Key property on the Properties section click the button and you will be able to see the IssuerName and IssuerKey.

NamespaceManager is the main class in the API once you have created an instance of this you can go on and manipulate things. Next thing we would like to do is to create a topic, Following code checks if there is a topic already created for the Chat if not then it creates it.

_myTopic = !_namespaceManager.TopicExists(ChatTopic) ? _namespaceManager.CreateTopic(ChatTopic) : _namespaceManager.GetTopic(ChatTopic);

all good except I have not explained what a topic is, “A topic is a durable message log with multiple subscription taps separately feeding subscribers” So topic is a central entity against which all the messages are published, and as many as 2000 subscribers can subscribe to it. Once a message is posted to a topic a copy of this message is sent to each of the subscribers. 

Speaking of subscriptions here is the code which will create the subscriptions to our newly created topic.

if (_namespaceManager.SubscriptionExists(_myTopic.Path, clientName))
            {
                _namespaceManager.DeleteSubscription(_myTopic.Path, clientName);
            }

            _namespaceManager.CreateSubscription(_myTopic.Path, clientName,
                                                 new SqlFilter(string.Format("From <>'{0}’", clientName)));

For the chat application we are creating one subscription for each client, we are checking if there is a subscription already I am deleting and creating a new one. This code also shows another aspects of the subscriptions that they can be selective i.e. you can tell what type of messages posted on the topic you are interested in. Here I am specifying that I am not interested in the messages sent by myself, which kind of makes sense for a chat application. Here “From” is a property of the message which contains the user name of the user who sent the message. In our application a chat message is represented by a ChatMessage Class

public class ChatMessage
    {
        public string Message { get; set; }
        public DateTime ReceivedTime { get; set; }
        public string From { get; set; }
        public string Id { get; set; }

    }

but we do not send this message as it is. More on this later let us carry on with the constructor code

              var factory = MessagingFactory.Create(serviceUri, tokenProvider);
            _myTopicClient = factory.CreateTopicClient(_myTopic.Path);
            _mySubscriptionClient = factory.CreateSubscriptionClient(_myTopic.Path, clientName, ReceiveMode.ReceiveAndDelete);

As all good chat applications our application will send and receive messages _myTopicClient will be used to send the messages and _mySubscriptionClient will be used to receive the messages.

Let us talk about sending first,

public void SendMessage(ChatMessage chatMessage)
        {
            using (var message = new BrokeredMessage())
            {
                message.CorrelationId = chatMessage.From;
                message.Properties.Add("Message", chatMessage.Message);
                message.Properties.Add("From", chatMessage.From);
                message.Properties.Add("Id", chatMessage.Id);

                _myTopicClient.Send(message);
            }

        }

simple enough I guess. Just keep in mind that

“Maximum message size: 256KBMaximum header size: 64KBMaximum number of header properties in property bag: MaxValue Maximum size of property in property bag: No explicit limit. Limited by maximum header size.”

Now let us talk about receiving the message. Service bus messages are received by polling on the service bus “kaachhaaan” I can hear the sound of breaking heart but well this is true no events guys not for now at least. Here is the code that does “the magic”.

var task = new Task(ReceiveMessageTask);
            task.Start();

Started a task to start a separate thread for polling, may not be the best way to do it but it works we are good to go here.

private void ReceiveMessageTask()
       {
           while (true)
           {
               var message = _mySubscriptionClient.Receive(TimeSpan.FromSeconds(2));

               if (message == null) continue;

               var chatMessage = new ChatMessage
                                     {
                                         From = (string)message.Properties["From"],
                                         Id = (string)message.Properties["Id"],
                                         Message = (string)message.Properties["Message"],
                                         ReceivedTime = DateTime.Now
                                     };

               FireMessageReceived(chatMessage);

          }

       }

so we poll for message after every 2 seconds and if we receive a message we fire an event which is handled by the ViewModel which get the message and updates the UI.

Here is where I am chatting to myself

image

(ignore the “Not Connected” label on the left)

You can open as many applications as you want about (2000) to be precise give them different names and they will work.

Do try this at home. I have given the example of a chat application to explain some of the concepts in azure appfabric service bus. Of course I do not believe it to be a rightful use of this technology. Service bus is used to enable applications to talk to each other. If you would like to dig deep into how and where the service bus should be used I recommend looking into sessions of Udi Dahan. They are not related to AppFabric service bus but give you a great insight to the scenarios where it can be used.

You can download the full application code from this link

http://ge.tt/92ik9B8?c

Please do not mind the strange namespace name “DropBoxChatApp” as this is a story of another time.

Have fun guys

2 thoughts on “Topics, Subscriptions and Receivers in Windows Azure App Fabric Service Bus

  1. Hi,

    Good post. I think the simple scenarios are the best way to learn and explain the technologies.

    >>Service bus messages are received by polling on the service bus “kaachhaaan” I can hear the sound of breaking heart but well this is true no events guys not for now at least.

    AppFabric uses “sticky polling”, so even if you poll with a 60 second timeout, the receive method will return a message as soon as one is available on the queue, or return null after 60 seconds. Even though it is a polling consumer you do effectivly get the low latency of an event driven consumer. Setting a higher timeout will probably result in fractinaly better performnace as there may be some overhead the recieve call. It might be worth testing this in the chat application.

    Regards,

    Alan Smith

  2. Alan thank you for the feedback.

    I believe you are right, the “Sticky polling” is a good alternate to the event model. You can use this and then build an event model for your application if you want to, as I have done in my code.

    regards,

    Ovais Akhter

Leave a comment