Windows Azure Service Bus & Web API a Match Made in Heaven?

September 5, 2013 — 7 Comments

ads_longpollA little while ago the Windows Azure team introduced the message pump pattern to Service Bus Message Bus SDK and it got me thinking about how I could leverage this from any web enabled client.

I wanted to create a long polling REST service that would allow me to extend the message pump pattern over a protected REST service. This is my proof of concept and should not be used in production without a little exploration.

A long poll means that a client makes a request to the server. The server then delays the response until an event occurs. Keep in mind that this is especially useful when you want to communicate events to clients through firewalls. Furthermore, this is a great way to reduce the number of requests made by clients. On the other hand, long poll requests eat up resources, therefore you will need to load test your endpoints in order to identify their limits.

The Message Source

I used the following Windows Form application to push messages to a Windows Azure Service Bus Topic.

9-6-2013 1-58-54 AM

The following code creates a TopicClient, it then pushes a message to the Windows Azure Service Bus Topic and increments a counter.

public partial class Form1 : Form
{
    private readonly TopicClient client;
    private int count;
    public Form1()
    {
        InitializeComponent();

        var connectionString = CloudConfigurationManager.GetSetting("ServiceBusConnectionString");
        var namespaceManager = NamespaceManager.CreateFromConnectionString(connectionString);
        var topicDescription = namespaceManager.GetTopic("alex-topic");
        client = TopicClient.CreateFromConnectionString(connectionString, topicDescription.Path);
    }

    private void button1_Click(object sender, EventArgs e)
    {
        var message = "message " + count;

        client.Send(new BrokeredMessage(message)
        {
            Label = "test"
        });
            
        count ++;
    }
}

The Message Pump REST Service

Using Web API I created an asynchronous REST endpoint. It connects to a topic subscription on a Windows Azure Service Bus namespace and uses the message pump to retrieve Brokered Messages as they arrive. If no messages have been received within 10 seconds of the requests reception, the endpoint responds with a
No Content (204) Http Status Code.

Implementing the service using Web API might not be the best approach, but it allowed me to easily test this scenario by creating a long poll endpoint.

The ReceiveBatch method is used to request 200 Brokered Messages that arrive within a period of 10 seconds. Then the received messages are concatenated and returned to the client.

public class PumpController : ApiController
{
    public async Task<HttpResponseMessage> Get()
    {
        return await Task.Run(() =>
        {
            var connectionString = CloudConfigurationManager.GetSetting("ServiceBusConnectionString");

            var namespaceManager = NamespaceManager.CreateFromConnectionString(connectionString);

            var topicDescription = namespaceManager.GetTopic("alex-topic");

            var client = SubscriptionClient.CreateFromConnectionString(connectionString,
                                                                        topicDescription.Path,
                                                                        "alex-subscription",
                                                                        ReceiveMode.ReceiveAndDelete);

            var response = new HttpResponseMessage(HttpStatusCode.NoContent);

            var msg = client.ReceiveBatch(200,TimeSpan.FromSeconds(10d));
            if (msg != null)
            {
                var message = msg.Aggregate("",(s, brokeredMessage) => s +
                                                                       Environment.NewLine +
                                                                       brokeredMessage.GetBody<string>());
                response = new HttpResponseMessage(HttpStatusCode.OK)
                {
                    Content = new StringContent(message)
                };
            }
            return response;
        });
    }
}

The Message Pump REST Service Client

9-6-2013 2-13-13 AM

The client is composed of a continuous loop which keeps polling from the service.  As it can be observed from the console application, every time the client queries the service, it receives the messages that were added since the its last request.

To make requests to the REST service I used a RestClient which I previously built using .Net 4.5 and the Enterprise Library Transient Block. You can read all about it in my blog post entitles “Asynchronously Calling REST Services From a Windows Azure Role”.

static void Main(string[] args)
{
    var tokenSource = new CancellationTokenSource();

    var token = tokenSource.Token;
    Task.Run(() =>
    {
        while (!token.IsCancellationRequested)
        {
            Console.WriteLine("called service |> " + DateTime.Now);
            RestClient.Uri("http://localhost:1928/api/pump&quot;)
                    .GetAsync((uri, code, value) => Console.WriteLine(code.ToString()))
                    .ContinueWith(task => Console.WriteLine(task.Result), token)
                    .Wait(token);
        }

    }, token);

    Console.ReadLine();
    tokenSource.Cancel();
}

Final Thoughts

Although this is only a proof of concept, I see some potential because this solution can be load balanced over multiple Web Role instances. The complete flow from the message source to the client felt snappy (on average less than 100 millisecond round trip delays) and I’m quite curious about the maximum load.

How would you implement a long poll enabled REST service?

7 responses to Windows Azure Service Bus & Web API a Match Made in Heaven?

  1. 

    I think there is a better way of doing this. Recently I implemented a similar concept that works like this:

    1. MVC web application hosts a page whose view uses SignalR.
    2. When web browser loads this page, it establishes connection the SignalR hub and a executes some (async) Foo() method on the hub.
    3. SignalR hub’s Foo() method will send a FooRequested object over Service Bus and waits for response.
    3. Worker role receives this FooRequested object, handles it and responds (using SessionId on the brokered message, etc) with a FooProcessing object.
    4. SignalR hub’s Foo() method receives its response, realises it has been successfully handled and sets up a AcceptMessageSessionAsync with the Service Bus.
    5. SignalR hub then initiates one or more ReceiveAsync or ReceiveBatchAsync calls on the message session it has opened.
    6. Worker role begins pushing through FooUpdated objects (with SessionId).
    7. SignalR hub receives these and transforms them and passes them onto the hub’s connected clients.

    Advantages: 1) Leans on a known-good API to perform the web signalling protocol; avoids hand rolling or needing to know anything at all about long-polling and all that low level stuff. 2) Keeps the MVC Controller clean from dealing in messaging concerns, and moves the logic to somewhere more appropriate that is already dealing in messaging concerns: a SignalR hub. 3) Makes for a good new use of the often somewhat “dusty” AcceptMessageSession feature in Azure S/B.

    Like

    • 

      Good point, but can I use SignalR from Silverlight, IOS, Android, Windows Phone, WPF or WinRT?

      Like

      • 

        You can use SignalR from all those platforms assuming you’re using Xamarin for the iOS and Android platforms. Sure, SignalR is a more suited to more coupled systems than a REST API would be. But it’s all about choosing the right tool for the job. If you aren’t exposing a public API that needs to version well or support multiple content representations then quite often REST can be considered over-engineering. Where something slightly tighter coupled, RPC-like, mechanism which SignalR provides may be a better solution.

        Like

        • 

          I completly agree with that.

          have you hit aby major pain points with xamarin?

          Like

          • 

            Not really, but I’m still in early’ish stages and so far I’m only using Xamarin Android. They are adding full PCL support (it sort of supports it now, but it’s a bit undocumented and glitchy per se) in the next release. I don’t see why any .NET developer would consider anything else when it comes to mobile development. Xamarin is easily good enough for production apps.

            SignalR + Xamarin is going to be a force to be reckoned with I feel. Send a push notification to the phone, the app wakes up and connects to the cloud’s SignalR hub, then your cloud can directly invoke methods on the phone app. It’s a much better architecture and means you can make the app far more a “dumb” “thin” client than they are today. Means you can keep more of your domain logic in the cloud, and reduce your app’s surface area which makes maintaining the apps across multiple platforms easier.

            Like

Trackbacks and Pingbacks:

  1. Dew Drop – September 6, 2013 (#1,619) | Morning Dew - September 6, 2013

    […] Windows Azure Service Bus & Web API a Match Made in Heaven? (Alexandre Brisebois) […]

    Like

  2. The Top 10 Most-Read #WindowsAzure Posts of 2013 | Alexandre Brisebois - December 29, 2013

    […] Windows Azure Service Bus & Web API a Match Made in Heaven? – 1,061 reads […]

    Like

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.