DBPedias

Your Database Knowledge Community

Christian Weyer's Blog

  1. Cross-device/cross-location Pub-Sub: Using Windows Azure Service Bus Topics Subscriptions in iOS with MonoTouch

    Windows Azure has seen some updates over the past weekend. One small update is that the Service Bus and Access Control Service are no longer marketed inside the Windows Azure AppFabric brand but are now a substantial part of Windows Azure core.

    The Windows Azure Service Bus has two basic feature sets:

    • relayed messaging (through the Service Bus Relay service)
    • brokered messaging (through queues, topics, subscriptions (and the deprecated message buffers)

    In this post I show you how to use part of Service Bus’ REST API to create a cross-platform & cross-location publish & subscribe app by leveraging topics and subscriptions.

    First of all, let’s launch the wonderful Service Bus Explorer tool and look at my Service Bus namespace:

    image

    As we can see there are no topics and subscriptions (and also no queues).

    What we are going to do is have a .NET console app running on Windows to create a topic and a subscription on the Service bus with the REST API and send messages to the topic. Here is the essential piece of code to do this:

       1:  var broker = new BrokeredMessaging (serviceNamespace);
       2:              
       3:  try
       4:  {
       5:      token = broker.GetToken (issuerName, issuerSecret);
       6:                  
       7:      string topicName = "newstopic";
       8:      string subscriptionName = "iphonesubscription";
       9:   
      10:      broker.CreateTopic(topicName);
      11:      broker.CreateSubscription(topicName, subscriptionName);
      12:                  
      13:      while (true)
      14:      {
      15:          broker.SendMessage (topicName, "Hello " + Guid.NewGuid ().ToString ());
      16:          Thread.Sleep (5000);                    
      17:      }
      18:  }
      19:  catch (WebException we)
      20:  ...


    Admitted, the actual heavy work is inside the BrokeredMessaging class. This class is just a simple wrapper around the REST API, and you can see some basic operations using WebClient to talk to the Service Bus in the AppFabric SDK samples (e.g. the Management Operations using REST sample).

    The BrokeredMessaging helper class can be found in the sample projects download at the end of this post.

    After we retrieved a token from ACS we create a topics and a subscription and send out messages in a loop:

    image

    These messages are sent to the Service Bus to a durable topic (which uses queues underneath). As long as there is no subscriber which gets and deletes the messages from the subscription we can see the messages sent to the topic in the Service Bus Explorer – here we have sent out 4 messages from the Console application:

    image

    Cool.

    Now let’s use a subscriber to get the messages from the subscription. My goal was to have a native iOS app but built with C# entirely. Therefore I fired up MonoTouch and created a very simple iPhone app. For the super-sophisticated UI I used MonoTouch.Dialog, a highly recommend UI library to quickly create any forms-over-data user interface for iOS apps.

    In order to talk to the Service Bus the MonoTouch project was using the exact same BrokeredMessaging class as my Windows console application. The joy of MonoTouch.

    Again, the essential code (after getting a token from ACS) to get and delete messages from the SB subscription looks like this (the messages object is the list of elements in the UI to display the messages).

    private void RegisterMessagesHandler ()
    {
        Task.Factory.StartNew (() =>
        {
            while (true)
            {
                try
                {
                        
                    var message = broker.ReceiveAndDeleteMessage (topicName + 
                       "/Subscriptions/" + subscriptionName);
                        
                    if (!String.IsNullOrWhiteSpace (message))
                    {
                        InvokeOnMainThread (delegate 
                        { 
                            messages.Elements.Add (new StringElement (message));
                            dvc.TableView.ReloadData ();
                        });
                    } 
                        
                }
                catch (Exception ex)
                {
                    Console.WriteLine (ex);                
                }
            }
        });
    }


    Note: it may not be wise to store the Service Bus owner and shared secret directly in the device’s app – you know… or at least store it in the Keychain (sample with MT: http://www.wildsau.net/post/2011/02/01/iOS-Store-passwords-in-the-keychain-using-MonoTouch.aspx).

    To convince you that there is no magic or cheating going on, this is the code from BrokeredMessaging  to get the message from the subscription (and also delete it):

       1:  public string ReceiveAndDeleteMessage (string relativeAddress)
       2:  {
       3:      string fullAddress = baseAddress + relativeAddress + 
       4:        "/messages/head" + "?timeout=60";
       5:              
       6:      Console.WriteLine ("\nRetrieving message from {0}", fullAddress);
       7:              
       8:      var webClient = new WebClient ();
       9:      webClient.Headers [HttpRequestHeader.Authorization] = token;
      10:   
      11:      var response = webClient.UploadData (fullAddress, 
      12:        "DELETE", new byte[0]);
      13:      var responseStr = Encoding.UTF8.GetString (response);
      14:   
      15:      Console.WriteLine (responseStr);
      16:              
      17:      return responseStr;
      18:  }

    Note: Console.WriteLine(…) is the mechanism in MonoTouch to write to debug output. Well…

    Whenever we get a real and non-empty message we add it to the list view of our simple iOS app. Voila:

    image

    And to prove that everything worked as expected, the subscription is now empty and no more messages are in there:

    image

    Bingo! Smile

    Windows Azure Service Bus (together with the Windows Azure Access Control Service) enables us to send messages in an async manner to durable storage in the Cloud and subscribing to those messages (via topics and subscriptions) with literally any device, any platform, from any location!


    The sample projects for VS 2010 and MonoTouch can be downloaded:


    Hope this helps.

  2. Unterlagen Demos zu meinen Sessions Workshop auf der BASTA! 2011

    So – die BASTA! ist vorbei und wir von thinktecture hatten mal wieder eine super Zeit in Mainz. Danke an das Team von S&S Media und vor allem an die Teilnehmer!

    Hier finden Sie die Folien und Beispiele zu meinen Sessions und dem Workshop auf der Herbst-BASTA! 2011:

    • Nicht nur Web: Android und iOS Apps mit HTML5 und Co. (Slides | Samples)
    • Kommunikation über die Cloud: Windows Azure AppFabric Service Bus (Slides | Samples)
    • Offen für's "Web": Web APIs mit WCF in .NET 4.0+ (Slides | Samples [this is the Preview 5 branch with samples])
    • Hands-On Windows Azure Platform: Ihr Tag in der Cloud [mit Dominick Baier] (Samples)

     

    Wenn Fragen sind wie immer eine EMail an mich (schauen Sie einfach in den Slides nach…). Danke.

    Bis bald!

  3. Erm, whats happening? Updating Windows Azure role configuration

    Sometimes the question shows up why the change of configuration of a Windows Azure deployment does not take effect immediately (whatever that means Smile).

    If you change the configuration (via the portal or via the management API) of your Windows Azure deployment then the change will happen almost immediately.
    Well, not exactly.

    The change will be rolled out to the instances using upgrade domains.

    image

    Source: Ryan Dunn’s TechEd 2010 presentation “Deploying, Troubleshooting, Managing and Monitoring Applications on Windows Azure”


    For each upgrade domain a status change event will be raised and the instance can decide whether it will handle the change or whether it needs to be restarted.
    Once the instances in that upgrade domain have reported that they are ready (either by handling the change, or by coming back online after restarting) then the fabric controller will move to the next upgrade domain.

    Hope this helps.

  4. iAzure: Mobile HTML apps Windows Azure Storage

    Currently I am researching how to design and build mobile HTML-based apps for various device platforms (iOS, Android and Windows Phone 7). For this I was looking for a good development and deployment strategy – and I think I found it: Windows Azure!

    The idea is the following:

    • use Windows Azure Blog Storage to host the HTML, CSS, JS and resource files
    • use a 3rd party tool to map my blob storage account as a folder in my local Windows Explorer
    • just open the files from this mounted folder in Visual Studio and work with them
    • save the files ‘locally’ (which actually saves them to Windows Azure Blob Storage)
    • access the HTML ‘app’ from your device with a custom DNS domain name mapped to your Windows Azure Blob Storage

    Ok, one step after the other.

    If you are looking for a tool to use various cloud storage providers (like Amazon S3 or Windows Azure Blog Storage) and mount your storage accounts locally in Windows Explorer, then I would recommend you to look into Gladinet Cloud Desktop.

    So, let’s mount one of my Windows Azure Blob Storage accounts via Cloud Desktop. In the Virtual Directories Manager navigate to Virtual Directories and click the Mount symbol:

    image


    Select the Windows Azure Blob Storage provider and give it a name (this will be the name of the mounted folder in Windows Explorer):

    image


    On the next page you need to specify the storage credentials:

    image


    And voila! We have our blob storage account mapped locally (OK, I already placed two files in there…):

    image


    As this is now a Windows Explorer mounted drive and folder we can simply open up the HTML file in Visual Studio, change it, and save it:

    image


    OK – on to finishing the re-requisites to finally access the HTML page.
    I do not want to expose and use the original Windows Azure Blob Storage URL and therefore map it to one of my domains like this (details of this process can be found here):

    image


    With the custom domain mapping set up I can now access the HTML page from my mobile device:

    image


    Note:
    this sample HTML page uses JavaScript to request data from a WCF ‘REST’ service which is exposed via the Windows Azure AppFabric Service Bus.


    Hope this helps.

  5. iPush-up: notifying mobile HTML apps from your server code

    In my previous post I talked about ‘hosting’ HTML pages (and later apps) in Windows Azure Blob Storage. Now I am going to explain what the sample HTML page showed there can do:
    when the page is loaded in the browser of our mobile device we will be able to push data/messages from any application through a Cloud service into the device.

    How can this be achieved?
    First, I am going to use a Cloud service called Pusher. Pusher enables large scale push-style communications from any code directly into out HTML pages/apps (including mobile devices like the iPhone, iPad or Android devices).

    Note: where it says ‘Server’ we could have just any kind of application.

    Pusher tries to use WebSockets, and if it is not available or does not succeed it falls back to a Flash-based socket communication. Have a look here which browsers are supported.

    For the purpose of this blog post, we will need to code artifacts:

    • JavaScript in an HTML page running on a mobile device browser
    • sample Windows Forms application pushing messages through Pusher into the devices


    Good news is that Pusher is offering a JavaScript object model which offers access to their public REST API. And the JS library is really very easy to use – just create a Pusher object, subscribe to a channel and and bind to events, e.g.:

    <head>
        <title>thinktecture tecTeacher</title>
        <script src="http://js.pusherapp.com/1.7/pusher.js" type="text/javascript"></script>
        <script type="text/javascript">
            // Enable pusher logging - don't include this in production
            Pusher.log = function () {
                if (window.console) window.console.log.apply(window.console, arguments);
            };
    
            // Flash fallback logging - don't include this in production
            WEB_SOCKET_DEBUG = true;
    
            var pusher = new Pusher('MY_APP_KEY');
            pusher.subscribe('tecteacher_episodes');
            pusher.bind('new_episode_available',
              function (data) {
                  alert("Pusher: " + data);
              });
        </script>
    .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }


    Easy going.

    On the server/pushing side we want to have a similar experience. And we are in luck, there is PusherDotnet which we can use in our .NET code:

    var provider = new PusherProvider(applicationId, applicationKey, applicationSecret);       
    var request = new SimplePusherRequest(
        textBoxChannel.Text, 
        textBoxEvent.Text, 
        textBoxPushText.Text);
    
    provider.Trigger(request);
    .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }


    I am sure you understand this code snippet without any further comment Smile.

    Now, when running the Windows Forms pushing app…

    image_thumb[4]


    … tadaaa!
    We can see the the notification message being delivered to the HTML page (which still being served from Windows Azure Blob Storage, BTW) running on my iPhone (actually to Mobile Safari):

    image


    Very powerful stuff!

    Hope this helps.

  6. Argh, my Azure deployment hangs forever - and now? (aka seeking help from Windows Azure support)

    I had this question coming up a couple of times – here goes:
    if you are using the the new portal, then on the left there is a link for "Help and Support".

    image

    From there you can find a section called "Troubleshooting and Support", and the actual support link is under "Get More Help in the Support Center".

    image

    The ladies and gentlemen from support can surely help you with your Windows Azure issues Smile

    Hope this helps.

  7. Sharding your SQL Azure databases today? (just a link)

    Without having to wait for SQL Azure Federations I was looking around for solutions to easily shard SQL Azure-based databases.
    Turns out I just came across this library which supports to spread the load of database queries over multiple databases (actually both, SQL Server and SQL Azure). Internally it is using the Task Parallel Library (TPL).

    Enzo SQL Shard (on CodePlex)


    Note: I did not yet look deeper into this library nor actually use it. Just thought I should share the link as it sounds quite interesting.

    Hope this helps.

  8. Is my cloud still supported (the Windows Azure OS, that is)?

    Have you ever asked yourself what the support lifetime of Windows Azure Guest OSes is?
    Turns out their lifecycle follows the same timeline as their Windows Server counterparts.

    That means:

    Hope this helps.

  9. Poor mans approach to application pool warm-up for IIS in a Windows Azure web role

    This is another small but quite useful idea and snippet from a real Windows Azure project.

    We all know that after deploying our web role to the Cloud that the first request would take a looong time. A web site’s application pool needs to be spawned, ASP.net compilation kicks in etc.
    In order to already have a web site up and running and pre-warmed there are several approaches, some of them being intrinsically supported by ASP.NET – but a bit complex, IMO - and some still in beta, AFAIK. But we do not need no magic feature for this. We already have the WebRole.cs with the RoleEntryPoint-derived class. Here we do our initialization and potentially our background work.

    And what could be a better candidate than periodically calling a certain (maybe the base) URL of a web site in order to keep the app pool up (if you want so!).

    The following code exactly does this – based on the name of a Windows Azure internal or input endpoint (which belongs to a web site) we simply call the base address of that endpoint for the current role instance:

    using System;
    using System.Net;
    using Microsoft.WindowsAzure.ServiceRuntime;
    
    namespace Thinktecture.WindowsAzure
    {
        public static class WebSiteUtilities
        {
            public static void WarmUp(string endpointName)
            {
                try
                {
                    var endpoint = RoleEnvironment.CurrentRoleInstance
                      .InstanceEndpoints[endpointName];
                    var address = String.Format("{0}://{1}:{2}",
                        endpoint.Protocol,
                        endpoint.IPEndpoint.Address,
                        endpoint.IPEndpoint.Port);
                    var webClient = new WebClient();
                    webClient.DownloadString(address);
                }
                catch (Exception)
                {
                    // intentionally swallow all exceptions here.
                }
            }
        }
    }
    .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }


    The actual initial and recurring warm-up call can then be placed into the Run method our our web role:

    public class WebRole : RoleEntryPoint
    {
        public override void Run()
        {
            try
            {
                while (true)
                {
                    Trace.WriteLine("Warming up web site...");
                    WebSiteUtilities.WarmUp("HttpIn");
    
                    Thread.Sleep(TimeSpan.FromMinutes(19));
                }
            }
            catch (Exception ex)
            {
                DiagnosticsHelper.WriteExceptionToBlobStorage(ex);
            }
        }
    }
    .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }


    Done.
    Note: I chose 19 minutes here between the calls as the default idle timeout of an IIS application pool is 20 minutes. You may want to change this to your own defaults or logic.

    Hope this helps.

  1. « First
  2. ‹ Previous
  3. 3
  4. Next ›
  5. Last »