How to write a Mobile Mash-Up


(Or, Using Direct Push to Build Low-Latency, Offline-Capable Mobile Applications)

A little over a year ago, we wrote an article that described the motivation for and design of Direct Push, the mechanism that Exchange uses to quickly replicate the changes that occur in the mailbox of a user down to the mobile device of that user. When describing this mechanism to people, we draw a diagram similar to the following[1]:

At step one, the device issues the request; at step two, we wait for the heartbeat interval to expire or for changes to occur in the mailbox of the user; and at step three, we complete the request with a payload that tells the device to sync the changes or simply initiate the next Direct Push session.

What usually happens after we walk through that diagram is that someone wonders aloud whether that open connection from the device to the enterprise can be used for applications other than email. When we were prototyping Direct Push, our inner monologue wondered this same thing.

In this article, we will show how this can be done by building a "mash-up"; that is, by using publicly-accessible web services for our own nefarious purposes. Our application will work like so:

- A server-resident component will fetch the five day weather forecast from weather.msn.com, generate a GIF image for the admin console from the XML that was fetched, and write the forecast for the current day as a special email message into the mailbox of each user that has been provisioned for this service.

- A device-resident "peer" of the server component of our application will event off of the arrival of the special email message, extract the forecast payload, and render it to the home screen of the device.

- The server will periodically fetch the weather forecast, and the device will be using Direct Push in order to get updates to the forecast as soon as they become available. Thus, the user will have up-to-date weather forecast information displayed right on the home screen of his or her device.

We provide the full source code for this application towards the end of the article.

Setup

The server component of our application will be a simple ASP.NET page. Here is how to get setup:

1. On the Exchange 2003 SP2 front-end server, open a cmd window and issue the following commands:

cd \inetpub\wwwroot

mkdir weather

2. In the IIS management console, right-click on the "weather" node in the tree view, select "Properties", click the "Create" button to create the ASP.NET application.

3. Select the "Directory Security" tab, and click the top-most "Edit..." button to bring up the "Authentication Methods" dialog. Disable "Enable anonymous access", enable Basic auth, and click OK.

4. Select the "Directory" tab, select "ExchangeApplicationPool" from the "Application pool" pulldown, and click OK to close the property dialog.

5. Right-click on the "weather" node again, select "Properties", select the "ASP.NET" tab, and select version 2.0.50727 from the pull-down menu.

6. Back in your command window, run:

\windows\microsoft.net\framework\v2.0.50727\aspnet_regiis -i

7. Copy the files style.css, global.asax, web.config, and default.aspx and the directory "images" into the "weather" directory.

Now, you should be able to successfully load http://server/weather/ and see something similar to the following, which depicts the current five day weather forecast for Seattle[2]:

Setting up the client component is simple:

1. Copy the CAB file to the PocketPC device (or emulator) and run it from there.

2. Provision ActiveSync on the device with the account information of a user who's got a mailbox that is accessible from the Exchange front-end on which you setup the server component.

3. Make sure that Direct Push is enabled by setting the synchronization schedule to "As items arrive" on the device. This is the default setting for the device, so it may already be setup for this.

Running the Application

At this point, we've got our application installed on the server and on the device. After provisioning the user with ActiveSync on the device to sync with the server, we'll setup that same user with our weather application: click on "add user", enter the user's login name, and hit return. When you click "send update" on the server application, the forecast should appear on the device within seconds.

All that's really going on here is, we are exploiting the push synchronization mechanism to act as a transport for our application data, and we're counting on the device side of an ActiveSync partnership to be storing that data away somewhere. Fine, you say, but why is this cool? Well, let's recall the "alternate title"[3] of this article ("Using Direct Push to Build Low-Latency, Offline-Capable Mobile Applications") and then consider the following points:

- Using ActiveSync to move our application data back and forth absolves our application of dealing with network connectivity; instead, it just deals with fully formed objects that "appear" on the device and on the server.

- Using Direct Push takes this a step further by guaranteeing that our application data is rapidly propagated to the device.

- Implicit in an ActiveSync partnership is some amount of device-resident storage, which allows our application to function even in the absence of network connectivity. So not only are we absolved of managing that connectivity by way of the first point, but we no longer even think in those terms. Instead, we think in terms of reacting to application objects that appear in our store, taking some domain-specific action on those objects, and submitting objects of our own for transmission to the server.

- Finally, the server component of our application is similarly liberated from worrying about things like device connectivity and connection management for thousands of devices. Instead, it can be written assuming that the device will connect when it can and application data will be delivered as soon as is possible.

For applications where the payload that you're sending in the email is itself viewable, the device email viewer (Pocket Outlook) is the perfect client-side peer for your server-side app. However, when your application requires some custom processing or handling once it reaches the device, you'll need to write a custom viewer of some kind. This is the case with our weather app: we don't want the user to have to navigate to the inbox to view the data - we want it readily visible on the home screen.

Now for some caveats:

- You'll notice that there is basically no error-handling in our code. We did this to keep the code simple and illustrative.

- The table of provisioned users isn't persisted anywhere, so each time the application pool gets recycled, you'll see your list of users vanish.

- The weather XML is fetched and the forecast image is generated each and every time the page is loaded - it should probably be cached.

- The DAV request URL that we use to create the email item that contains the forecast data has both the name of the mailbox server ("localhost", in our single-box topology) and the NT domain hard-coded. To support FE/BE topologies and deployments with multiple mailbox servers, this information will need to be retrieved from ActiveDirectory.

These types of loose ends would not exist for an enterprise-class application, but we are of course assuming that people just "get" this and will take what we've done and run with it.

Conclusion

This will all get a bit cleaner sometime in the Exchange 2007 timeframe, but enterprise deployment cycles being what they are, we figured that seeding the current ecosystem with this thinking was the right thing to do.

As promised, the code is attached to this post in a ZIP file; please click on the link below.

- Sami Khoury and Selva Nalliah



[1] Drawing a diagram on my whiteboard and taking a photo of that was so much simpler than bumbling my way through Visio. Visio guys, how about a whiteboard-to-vsd converter?

[2] No, really.

[3] Alternate titles are supposed to be long.


Comments (9)
  1. George says:

    Too Cool.  I can think of several applications where we could use this concept in our environment.  

    Thanks for the "push".

  2. martin says:

    Hi,

    I get the following error:

    System.Net.WebException: The remote server returned an error: (403) Forbidden. at System.Net.HttpWebRequest.GetResponse() at ASP.default_aspx.UpdateUser()

    Can you help please because I can think of a number of thing we can use this for.

    thanks,

    martin

  3. Exchange says:

    Martin,

    We’ll need more info before we can help.  What URL is the HttpWebRequest object accessing when that error is thrown?  Is it a single- or multi-box topology?

    Is SSL turned on?

  4. martin says:

    Hi,

    The exception happens in UpdateUser() when the first req.GetResponse().Close(); is executed.

    I call https://xxx.xxx.xxx.xxx/weather/ and I get the weather displayed in the browser and I can add a user. But when I click to update the user I get the exception.

    SSL is turned on.

    We run with a single exchange server for our domain.

    hope this helps,

    martin

  5. Exchange says:

    Martin,

    We beleive that this is caused by SSL being turned on on the "ExAdmin" virtual directory.

  6. Mike Hill says:

    Dear EHLO,

    Phat App ! All is right except for the error posted by Martin. I’m experiencing the same issue. On the ExAdmin dir, NO SSL is configured.

    In fact, the only dir using SSL is Exchweb.

    I would really like to get more info on this, as this is just what we are looking for to extend our free tracking and tracing application called Reperion. (not sneaky commercial, it’s free)

    Mike.

    M.D. http://www.reperion.com

  7. Exchange says:

    Mike, thanks for your interest.  Currently, this blog article is the extent of our publicly available information on this mechanism.  Regarding the error that you’re seeing, you might verify that you’ve followed the deployment steps properly and try hitting the exadmin URL from a browser in order to get more info on why it’s failing.

  8. mike says:

    Dear Exchange pplz,

    I dunno what I did to the server in the last few weeks, but now my error is reduced to :

    System.Net.WebException: The remote server returned an error: (404) Not Found. at System.Net.HttpWebRequest.GetResponse() at ASP.default_aspx.UpdateUser()

    when I try to update an added user.

    The server nicely gets the maps, I can log on locally or via the web, add user goes fine, update user fails.

    I just remember I haven’t installed the cab file anymore on my device. Will do that just now and try again. Please standby.

  9. LucidDreams says:

    Back again. Did install the weather cab file on the PPC. Still 404 not found. Deleted the cookies etc. Also tried from localhost instead of webpage. Also set detailed errors but still same error output.

    Will investigate further, I never give up :)

Comments are closed.

Skip to main content