My Store: Enqueue and Dequeue messages with Windows Azure Mobile Services and Service Bus

Introduction

This sample demonstrates how you can enqueue and dequeue messages from your Windows Store apps into a Windows Azure Service Bus Queue via Windows Azure Mobile Services.  This code sample builds out an ordering scenario with both a Sales and Storeroom and app.

Prerequisites

Scenario description

The idea of the scenario is to showcase a simple internal retail store application that communicates two different applications using a Windows Azure Service Bus queue to send/receive product orders.

Scenario flow

  1. The Sales app inserts a new order.

  2. The Order table’s insert script enqueues a Service Bus message including the order info.

  3. A scheduled job dequeues the Service Bus message and sends a push notification to the registered channels.

  4. The Storeroom app receives the push notification and refreshes the orders list.

Building the Sample

Follow these steps to set up the sample:

  1. Create a new Service Bus namespace in the Windows Azure Management Portal.

    To do this, log in to the Windows Azure Management Portal, go to Service Bus and then click Create.

    Create Button

    This displays the Create a namespace dialog box.

    In the dialog box, type a subdomain name for the new service bus namespace in the URL textbox and wait for name verification. If the name is available, you will see a check mark; if already in use, an exclamation mark will appear. Then, select the region where you want to create the service.

    Note: Pick the same region that you intend to choose for your mobile service. This will give you the best performance.

    Click the check mark to complete the process. You might have to wait several minutes as the system provisions resources for your account.

    Create a namespace dialog

    Once the service bus namespace is created, you need to obtain the Access Key. Select your service bus namespace and click CONNECTION INFORMATION on the bottom bar.

    Access key Button

    Make note of the service service bus namespace and the Default Key value, as you will use this information later to perform operations with the namespace.

    Access key dialog

  2. Add Push Notifications to the sample.

    Open the Windows Store App solution in Visual Studio. In Solution Explorer, right-click the MyStoreStoreroom Windows Store project, click Add and then Push Notification. This starts the Add Push Notification Wizard.

    Add Push Notifications

    Click Next, sign in to your Windows Store account, then supply a name in Reserve a new app name and click Reserve.

    push-notifications-step1

    Click the new registration in the App Name list, then click Next.

    push-notifications-step2

    Import your Windows Azure Subscriptions by clicking Import subscriptions....

    import-subscriptions

    In the Import Windows Azure Subscriptions dialog box, click Download subscription file, log in to your Windows Azure account (if required) and click Save when your browser requests to save the file.

    download-subscription-file

    Note: The login window is displayed in the browser, which may be behind your Visual Studio window. Remember to make a note of where you saved the downloaded .publishsettings file. You can skip this step if Visual Studio is already connected to your Windows Azure subscription.

    Click Browse, navigate to the location where you saved the .publishsettings file, select the file, then click Open and then Import. Visual Studio imports the data needed to connect to your Windows Azure subscription.

    import-subscription-file

    Security Note: After importing the publish settings, consider deleting the downloaded .publishsettings file as it contains information that can be used by others to access your account. Secure the file if you plan to keep it for use in other connected app projects.

    Back in the Add Push Notification dialog, click Create service... to create a new Mobile Service.

    create-service

    In the Create Mobile Service dialog, select your Subscription and the desired Region for your mobile service, then type a Name for your mobile service.

    Note: Mobile service names must be unique. A red X is displayed next to Name when the name you supplied is not available.

    In Database, select Create a free SQL Database, supply the Server user name, Server password, and Server password confirmation then click Create.

    configure-new-mobile-service

    Note As part of this sample, you create a new free SQL database instance and server. You can reuse this new database and administer it as you would any other SQL database instance. You can only have one free database instance. If you already have a database in the same region as the new mobile service, you can instead choose the existing database. When you choose an existing database, make sure that you supply correct login credentials. If you supply incorrect login credentials, the mobile service is created in an unhealthy state.

    Alternatively, you can create the mobile service from the Windows Azure Management Portal. Once logged in, navigate to Mobile Services and click New. then expand Compute | Mobile Service, then click Create and follow the instructions.

    Click the name of the mobile service that you created, then click Next and Finish.

    push-notifications-step3

    The mobile service is updated to register your app package SID and client secret and a new channels table is created. Mobile Services is now configured to work with Windows Push Notification Services (WNS) to be able to send notifications to your app.

  3. Next, you will update the generated code to store the obtained channel instance so it can be used by the application to handle the received push notifications.

    Open the generated push.register.cs file located in the services/mobile services/[your-mobile-service-name] folder and update the UploadChannel method to save the generated channel in the App.CurrentChannel property as highlighted below.

    <!-- mark:21-->
    C#
    Edit|Remove
    public async static void UploadChannel() 
    { 
        var channel = await Windows.Networking.PushNotifications.PushNotificationChannelManager.CreatePushNotificationChannelForApplicationAsync(); 
     
        var token = Windows.System.Profile.HardwareIdentification.GetPackageSpecificToken(null); 
        string installationId = Windows.Security.Cryptography.CryptographicBuffer.EncodeToBase64String(token.Id); 
     
        var ch = new JObject(); 
        ch.Add("channelUri", channel.Uri); 
        ch.Add("installationId", installationId); 
     
        try 
        { 
             await App.<your_mobile_service_name>Client.GetTable("channels").InsertAsync(ch); 
        } 
        catch (Exception exception) 
        { 
             HandleInsertChannelException(exception); 
        } 
     
        App.CurrentChannel = channel; 
    }
     
    
    
  4. Remove the code that sends a sample toast notification.

    In Server Explorer, expand Windows Azure, Mobile Services, your service name, and channels. Then, open the insert.js file. This file contains JavaScript code that is executed when a client sends a request to register a device by inserting data into the channels table; it checks for an existing registration for the device, and also contains code that sends a push notification when a new registration is added to the channels table.

    In the insert script, locate the line that calls to sendNotifications and comment it out, or remove it.

    Notification Sample

  5. Create a table named DeliveryOrder that will be used to keep track of the deliveries.

    Open Server Explorer, expand Mobile Services under Windows Azure, right-click your mobile service and select Create Table.

    Create a new Table

    Create a new table named DeliveryOrder and set the permissions for Insert, Update, Delete, and Read to "Anybody with the application key".

    Create Delivery Order Table

  6. Repeat the previous steps to create a table named Order that will be used to keep track of the new orders.

    Create Order Table

  7. Update the insert script for the Order table.

    Expand the Order table you just created. Then right-click the insert.js script file and select Edit script.

    Edit insert script option

    The script opens in an editor window. Here you can insert a JavaScript function that is going to be invoked whenever someone performs an insert (the item to be inserted is passed as a parameter).

    Update the content of the file with the code below in order to add the order message to the service bus queue. Replace the service bus namespace and key placeholders with the ones from the service bus namespace that you created before.

    <!-- mark:1-23 -->
    JavaScript
    Edit|Remove
    function insert(item, user, request) { 
        var insertInQueue = function() { 
            var azure = require('azure'); 
            var serviceBusService = azure.createServiceBusService('<namespace name>''<namespace key>'); 
     
            serviceBusService.createQueueIfNotExists('orders'function(error) { 
                if (!error) { 
                    serviceBusService.sendQueueMessage('orders', JSON.stringify(item), function(error) { 
                        if (!error) { 
                            console.log('sent message: ' + item.id); 
                        } 
                    }); 
                } 
            }); 
        }; 
     
        request.execute({ 
            success: function () { 
                insertInQueue(); 
                request.respond(); 
            } 
        }); 
    }
     
    
    

    When you save changes to the insert.js file, a new version of the script is uploaded to your mobile service.

  8. Create the scheduled job that will read the service bus queue and send push notifications to the registered clients whenever there are new messages in the queue.

    Navigate to the Windows Azure Management Portal and select Mobile Services. Select your mobile service, click the Scheduler tab and click Create a Scheduled Job.

    Create Scheduled Job

    In the scheduler dialog box, specify processOrder for the job name and make sure the schedule frequency is set to every 15 minutes. Click the check mark to create the job.

    Configure Scheduled Job

    Select the created job from the job list.

    Select New Job

    Select the Script tab and paste the code snippet shown below to check the service bus queue and send a push notification to all registered channels if new messages arrive to the queue. Replace the placeholders with the services bus namespace name and key.

    <!-- mark:1-65-->
    JavaScript
    Edit|Remove
    function processOrder() { 
     
        serviceBusService.createQueueIfNotExists('orders'function(error) {  
            if (!error) { 
                serviceBusService.receiveQueueMessage('orders', receiveMessageCallback); 
            } 
            else { 
                console.error(error); 
            }  
        }); 
    } 
     
    var azure = require('azure');  
    var serviceBusService = azure.createServiceBusService('<namespace name>''<namespace key>');  
    var receivedMessageCount = 0var notificationSent = false; 
     
    function receiveMessageCallback(error, receivedMessage) { 
     
        if (!error){ 
            receivedMessageCount++; 
     
            var order = JSON.parse(receivedMessage.body); 
     
            var deliveryOrderTable = tables.getTable('DeliveryOrder'); 
            deliveryOrderTable.insert({  
                product: order.product, 
                quantity: order.quantity, 
                customer: order.customer, 
                delivered: false                     
            }{ 
                success: function() { 
                    if (!notificationSent) { 
                        sendPushNotification('/Images/Logo.png''New orders''One or more orders have been placed'); 
                        notificationSent = true; 
                    } 
     
                    if (receivedMessageCount < 10{ 
                        // continue receiving messages until we process a batch of 10 messages 
                        serviceBusService.receiveQueueMessage('orders', receiveMessageCallback); 
                    } 
                }, 
                error: errorHandler 
            }); 
        } 
    } 
     
    function sendPushNotification(imagesrc, title, line1) { 
        var channelTable = tables.getTable('channels'); 
        channelTable.read({ 
            success: function(channels) { 
                channels.forEach(function (channel) { 
                   push.wns.sendToastImageAndText02(channel.channelUri, { 
                        image1src: imagesrc, 
                        text1: title, 
                        text2: line1 
                    }); 
                }); 
            } 
        }); 
    } 
     
    function errorHandler(error){ 
         console.error(error); 
    }
     
    
    

    Click the Save button to store the changes to the script.

    Save Job Script

  9. Switch back to Visual Studio and open the App.xaml.cs file in the MyStoreStoreroom project. Locate the mobile service's static field declaration at the top of the App class. Make note of the mobile service url and mobile service key.

  10. Update the MobileService static property to return the generated mobile service's static field declaration instead of null.

    <!-- mark:1,9 -->
    C#
    Edit|Remove
    private static MobileServiceClient <your_mobile_service_name>Client = new MobileServiceClient( 
            "{mobile-service-url}", 
            "{mobile-service-key}"); 
     
    ... 
     
    public static MobileServiceClient MobileService 
    { 
        get { return <your_mobile_service_name>Client; } 
    }
     
    
    
  11. Open the App.xaml.cs file in the MyStoreSales project and replace the placeholders {mobile-service-url} and {mobile-service-key} with the values obtained from the MyStoreStoreroom project.

Running the Sample

  1. In Solution Explorer, right-click the MyStore solution and select Properties.

  2. Select Common Properties in the left pane. In the right pane, select Multiple startup projects and change the action of the projects to Start, as shown below. Finally, click OK.

    Startup Options

  3. Press F5 to start the Sales and the Storeroom apps.

    Note: If this is the first time you run the apps, you may get an error message saying that the build restored the NuGet packages. If that is the case, run the apps one more time to include those packages in the build (for more information, see http://go.microsoft.com/fwlink/?LinkID=317568).

  4. In the main page of the Sales app, complete the form by specifying a customer name, a product, and the amount. Then, click Purchase.

    Sales App

  5. Go back to the Windows Azure Management Portal, select the Scheduler tab of your mobile service, and then click Enable in the command bar to allow the job to run.

    Enable Job Script

  6. To test your script immediately rather than waiting 15 minutes for it to be scheduled, click Run Once in the command bar.

    Run Job Script

  7. Switch to the Storeroom app. A toast notification should be received informing you that a new order has been placed.

    Storeroom App

  8. To receive new notifications, switch to the Sales app to purchase a new product. Then either trigger the job using the Run Once button from the Windows Azure Management Portal, or simply wait for the job to be scheduled.

Want to see More Windows Store app samples using Windows Azure Mobile Services - check out the full listing. If you cant find a specific Windows Azure Mobile Services scenaro in the full listing please feel free to reach out to me on Twitter via @cloudnick