Theory of a Cloud Based Photo Sharing App using Windows Phone and AzureBy Nick Randolph
In the next couple of posts we’re going to go on a bit of a tangent and discuss how you can connect your Windows Phone application to the cloud. Whilst a lot of these concepts can be applied to any of the cloud service providers, for the purpose of this discussion we’re going to focus on Windows Azure.
The example we’re going to work through is a photo sharing style application, Capture TechEd, which was actually created in preparation for my Phone+Cloud session at the recent TechEd NZ and TechEd Australia events. In summary the application allows a user to take a photo and share it to other users of the Capture TechEd application. The sequence of events is as follows:
- User takes a photo using the Capture TechEd application
- User enters a comment and assigns the photo to a particular TechEd Track
- Photo is uploaded to Blob Storage
- Uploaded photo URL, Comment and Track information is added to a Queue for processing
- Photo is dequeued and resized to 173×173 (the size of a Windows Phone Start tile)
- Toast Notification is sent to all users of the app to update their Start tile to the new photo.
In this post we’re going to go through each of these steps at a high level so that you understand the concepts. Then in subsequent posts we’ll go through each step in detail with the code that you’ll need to implement each step.
Step 1: Taking the Photo with the Camera
This is relatively self-explanatory – you need to use the CameraCaptureTask to take a photo with the camera and save it to isolated storage.
Step 2: Upload the Photo to Blob Storage
Writing to Windows Azure Blob Storage is relatively straight forward as it consists of making the appropriate
HttpWebRequest calls to
POST data to the URL where you want the blob to be stored. However, in order to write to Blob Storage you’ll need an access key but rather than package an access key within the application (not a good idea), Windows Azure supports a concept called Shared Access Signatures. You can think of these as tokens that can be allocated to grant applications permissions on protected resources. In the case of the Capture TechEd application we’re going to use a WCF Service hosted in Windows Azure to allocate time limited Shared Access Signatures that will grant the application write permissions to Blob Storage.
Figure 1 illustrates how the phone application firstly requests a Shared Access Signature and then uses it to
POST the photo to Blob Storage.
Step 3: Uploading the Processing Job
There are actually two steps here. The first is to retrieve the list of TechEd tracks from the TechEd OData feed. Once the user has selected which track to associate the photo with, the URL of the uploaded photo, the comment and the selected track are uploaded to another WCF service, again hosted in Windows Azure (Figure 2).
Step 4: Adding Job to Queue
Within the WCF service the uploaded job is added to a Windows Azure Queue (Figure 3). This is an extremely quick operation which prevents any blocking on the client whilst it waits for a response.
Step 5: Image Processing
A Worker Role (hosted in Windows Azure) picks up each job from the queue. It then retrieves the corresponding photo from Blob Storage, resizes it and saves it back to Blob Storage. The URL of the resized photo, the comment and the track are then added as a new record into SQL Azure (Figure 4). Due to the nature of SQL Azure it is not desirable to have any front-end application touch it directly. This means that you should try to separate your web site and services from it using a combination of Queue, Table and Blob Storage.
Step 6: Update Start Tiles via Notification
Once the record has been added to SQL Azure, all users of the application receive a tile notification to update the Start tile background image. As there may be a large number of potential users of the application it is important that the process of sending these notifications is also scalable. In order to send a single tile notification an application has to do a
Http POST to the
ChannelUri which corresponds to the device you want to send the notification to. If you sequentially iterate through each registered device this could take a very long time. Instead, add all the devices to another queue, that way you could potentially scale out the number of Worker Roles in order to optimise the time in which notifications are sent out (Figure 5).
Step 7: Retrieve Recent Photos
When the Capture TechEd application is run, the most recent set of photos are to be displayed within the application. In this step we’re going to use OData to present these photos (Figure 6). Ideally you’ll want to enable some form of output caching to make this efficient, otherwise each request will be connecting directly to SQL Azure which we’ve already discussed as being a big no-no.
One of the biggest challenges with working with the cloud is that you have to adjust the way that you approach the architecture of your application. If you look at Figure 7, which overlays each of the steps in this application, you’ll notice it’s very spaghetti-like in nature. Here we’ve traded of architectural simplicity (e.g. WCF Service backed directly onto a SQL Server database) for performance. Specifically the performance of the phone application – at every stage we’re aiming to reduce the wait time for the user to complete specific tasks.
One last thought to consider, which actually didn’t make it into the talk is how the phone application accesses the photos after they’ve been resized. As part of the resize operation the photos are uploaded back into Blob Storage. However, the URL that is written into SQL Azure, and subsequently used by the phone application to retrieve the resized photos actually routes via the CDN. The use of the CDN means that the phone is downloading the photo from the nearest distribution point, which in Australia is in Sydney, versus either Asia or the US for the underlying Blob Storage. This can yield significantly better performance, unless the user is unlucky enough to be the first person to access the resized photo as it will need to first be down loaded from Blob Storage to the CDN – automatically by the CDN of course!