(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:
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.
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:
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:
7. Copy the files style.css, global.asax, web.config, and default.aspx and the directory "images" into the "weather" directory.
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" 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.
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.
 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?
 No, really.
 Alternate titles are supposed to be long.