Windows Azure, .NET Services from a Windows Mobile Widget

[This post is based on the Windows Azure Tools for Microsoft Visual Studio July 2009 CTP]


That’s right, if you hadn’t guessed what I was working on with my previous posts on .NET Services (Tokens, Queues I, II, III, Routers I & II) I’ve been working towards accessing .NET Services from within a widget. I must apologise for the following as it’s just a code dump of a sample widget that shows how to create a queue and subscribe to an existing router.  Note that if you are going to use this on a number of devices you need to create a unique queue on each device, otherwise you’ll end up subscribing to the router multiple times – this will cause duplicate messages in your queue and contention between the devices dequeuing the messages.


To get this widget to work, simply create a widget (Developing Widgets for Windows Mobile 6.5) and then copy the following code into your html file.



<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”>
<html http://www.w3.org/1999/xhtml%22″ mce_href=’http://www.w3.org/1999/xhtml”‘>http://www.w3.org/1999/xhtml” >
<head>
    <title>Widget Chat</title>


      <script type=”text/javascript”>
          var theToken;
          var theRouter = “myrouter”
          var widgetQueue = “widget”;


          function connect() {
              var solutionName = document.getElementById(“SolutionNameText”);
              var solutionPassword = document.getElementById(“SolutionPasswordText”);


              alert(‘Solution Name: ‘ + solutionName.value);
              alert(‘Solution Password: ‘ + solutionPassword.value);
              httpGetAuthenticationToken(solutionName.value, solutionPassword.value, createQueue);
          }


          function createQueue() {
              alert(‘Creating Queue’);
              httpCreateQueue(theToken, widgetQueue, subscribeToRouter);
          }


          function subscribeToRouter() {
              alert(‘Subscribing to Router’);
              httpSubscribeQueueToRouter(theToken, theRouter, widgetQueue, pollForMessage);
          }


          function pollForMessage() {
              httpDequeueMessage(theToken, widgetQueue, messageReceived, pollForMessage);
          }


          function messageReceived(message) {
              alert(‘Message Received: ‘ + message);
              pollForMessage();
          }


          function send() {
              var messageBox = document.getElementById(“Message”);
              httpRouteMessage(theToken, theRouter, messageBox.value);
          }


          function httpGetAuthenticationToken(username, password, callback) {
              try {
                  http = new XMLHttpRequest();
                  http.open(“GET”, “
https://accesscontrol.windows.net/IssueToken.aspx?u=” + username + “&p=” + password);
                  http.onreadystatechange = function() {
                      if (http.readyState == 4) {
                          if (http.status == 200) {
                              theToken = http.responseText;
                              alert(‘Authenticated:’ + theToken);
                              callback();
                          }
                          else {
                              alert(‘Authentication failed’);
                          }
                      }
                  }
                  http.send();
              }
              catch (e) {
                  alert(e.message);
              }
          }


          function httpCreateQueue(token, queue, callback) {
              var policy = “<entry mce_href=’http://www.w3.org/2005/Atom”‘>http://www.w3.org/2005/Atom”>” +
  “<QueuePolicy mce_href=’http://schemas.microsoft.com/netservices/2009/05/servicebus/connect”‘>>” +
    “<ExpirationInstant>2009-09-03T01:00:00.0000000Z</ExpirationInstant>” +
  “</QueuePolicy>” +
“</entry>”;


              http = new XMLHttpRequest();
              http.open(“POST”, “
https://blogsample.servicebus.windows.net/” + queue, false);
              http.setRequestHeader(“X-MS-Identity-Token”, token);
              http.setRequestHeader(“Content-type”, “application/atom+xml;type=entry;charset=utf-8”);
              http.onreadystatechange = function() {
                  if (http.readyState == 4) {
                      if (http.status == 201) {
                          var created = http.responseText;
                          alert(‘queue created: ‘ + created);


                      }
                      else {
                          alert(‘queue not created – ‘ + http.status);
                      }
                      callback();
                  }
              }
              http.send(policy);
          }


          function httpGetServiceList(token) {
              http = new XMLHttpRequest();
              http.open(“GET”, “
https://blogsample.servicebus.windows.net/”, false);
              http.setRequestHeader(“X-MS-Identity-Token”, token);
              http.onreadystatechange = function() {
                  if (http.readyState == 4 && http.status == 200) {
                      output = http.responseText;
                      alert(output);
                      // Do something with the service list
                      httpRenewQueue(token, “mobilequeue”, output);
                  }
              }
              http.send();
          }


          function httpRenewQueue(token, queue, getResponse) {
              xmlDoc = new ActiveXObject(“Microsoft.XMLDOM”);
              xmlDoc.async = “false”;
              xmlDoc.loadXML(getResponse);


              var entry;
              var entries = xmlDoc.getElementsByTagName(“title”);
              var i;
              for (i = 0; i < entries.length; i++) {
                  if (entries[ i ].childNodes[0].nodeValue == queue) {
                      entry = entries[ i ].parentNode;
                  }
              }
              entry.getElementsByTagName(“ExpirationInstant”)[0].childNodes[0].nodeValue = “2009-08-31T09:56:25.2951184Z”;


              http = new XMLHttpRequest();
              http.open(“PUT”, “
https://blogsample.servicebus.windows.net/” + queue + “/!(queue)”, false);
              http.setRequestHeader(“X-MS-Identity-Token”, token);
              http.setRequestHeader(“Content-type”, “application/atom+xml;type=entry;charset=utf-8”);
              http.onreadystatechange = function() {
                  if (http.readyState == 4 && http.status == 200) {
                      var output = http.responseText;
                      alert(‘renew: ‘ + output);
                      httpEnqueueMessage(token, queue, “Hi Everyone”);
                  }
              }
              http.send(entry.xml);
          }


          function httpDeleteQueue(token, queue) {
              http = new XMLHttpRequest();
              http.open(“DELETE”, “
https://blogsample.servicebus.windows.net/” + queue + “/!(queue)”, false);
              http.setRequestHeader(“X-MS-Identity-Token”, token);
              http.onreadystatechange = function() {
                  if (http.readyState == 4 && http.status == 200) {
                      var deleted = http.responseText;
                      alert(‘deleted’);
                  }
              }
              http.send();
          }


          function httpEnqueueMessage(token, queue, message) {
              http = new XMLHttpRequest();
              http.open(“POST”, “
https://blogsample.servicebus.windows.net/” + queue, false);
              http.setRequestHeader(“X-MS-Identity-Token”, token);
              http.setRequestHeader(“Content-type”, “text/plain;charset=utf-8”);
              http.onreadystatechange = function() {
                  if (http.readyState == 4 && http.status == 202) {
                      var output = http.responseText;
                      alert(‘enqueue: ‘ + output)
                      httpDequeueMessage(token, queue);
                  }
              }
              http.send(message);
          }


          function httpDequeueMessage(token, queue, callback, noMessageCallback) {
              http = new XMLHttpRequest();
              http.open(“DELETE”, “
https://blogsample.servicebus.windows.net/” + queue + “/!(queue/head)?encoding=asreply&maxmessages=1&timeout=30”, true);
              http.setRequestHeader(“X-MS-Identity-Token”, token);
              http.onreadystatechange = function() {
                  if (http.readyState == 4) {
                      if (http.status == 200) {
                          var output = http.responseText;
                          callback(output);
                      }
                      else {
                          noMessageCallback();
                      }
                  }
              }
              http.send();
          }


          function httpRouteMessage(token, router, message) {
              http = new XMLHttpRequest();
              http.open(“POST”, “
https://blogsample.servicebus.windows.net/” + router, false);
              http.setRequestHeader(“X-MS-Identity-Token”, token);
              http.setRequestHeader(“Content-type”, “text/plain;charset=utf-8”);
              http.onreadystatechange = function() {
                  if (http.readyState == 4) {
                      if (http.status == 202) {
                          var output = http.responseText;
                          alert(‘Send ok!’);


                      }
                      else {
                          alert(‘Unable to send’);
                      }
                  }
              }
              http.send(message);
          }


          function httpSubscribeQueueToRouter(token, router, queue, callback) {
              var policy = “<entry mce_href=’http://www.w3.org/2005/Atom”‘>http://www.w3.org/2005/Atom”>” +
              “<link rel=’alternate’ href=’
https://blogsample.servicebus.windows.net/” + queue + “‘ />” +
  “<HttpHeaders mce_href=’http://schemas.microsoft.com/netservices/2009/05/servicebus/connect”‘>>” +
    “<HttpHeader name=’X-MS-Identity-Token’ value='” + token + “‘ />” +
  “</HttpHeaders>” +
“</entry>”;


              http = new XMLHttpRequest();
              http.open(“POST”, “
https://blogsample.servicebus.windows.net/” + router + “/!(router/subscriptions)”, false);
              http.setRequestHeader(“X-MS-Identity-Token”, token);
              http.setRequestHeader(“Content-type”, “application/atom+xml;type=entry;charset=utf-8”);
              http.onreadystatechange = function() {
                  if (http.readyState == 4) {
                      if (http.status == 200) {
                          var created = http.responseText;
                          alert(‘subscribed ok:’ + created);
                          callback();
                      }
                      else {
                          alert(‘not subscribed ok’ + http.status);
                      }
                  }
              }
              http.send(policy);
          }


      </script>
</head>
<body>
    <p>   
    Solution Name:<br />
    <input id=”SolutionNameText” type=”text” />
        <br />
    Solution Password:<br />
    <input id=”SolutionPasswordText” type=”password” /><br />
    <Button onclick=”connect()”>Connect</Button>
    </p>


    <p>   
    Message:
        <br />
    <input id=”Message” type=”text” /><br />
    <Button onclick=”send()”>Send</Button>
    </p>


</body>
</html>

Leave a comment