Windows Azure Mobile Services Realtime Collaborative To Do App

09 Apr 2013

Inspired by the first two talks at #stacked13 by Mike Taulty and then Maarten Balliauw I thought I'd jump straight into Windows Azure Mobile Services and build an a realtime collaborative synchronised todo list. I'd do this based on the Get started with data in Mobile Services HTML guide. I would then and host it on a Windows Azure web site.

Update: Sorry, I haven't renewed my Azure Mobile Services account so the demo is no longer available

realtime-todo

View the demo

Note: I want to publish this quite quickly so that people at the event can have a play. So, the rest of this post will be a bit of a brain dump and I'll tidy it up later

HTML/JavaScript Mobile Services To Do list

In Mike's talk he mentioned that the mobile service JavaScript library has just been released. So, this was an obvious starting point. Signing up for Azure and following the getting started guide was very simple.

You can see the code following the tutorial, with a bit of clean up, here. The main files to look at are index.html and app.js.

Making it realtime with Pusher

Pusher (who I work for) are listed in the Windows Azure store. So, the first thing to do is add Pusher as an add-on.

pusher-azure-addon

Once the addon has been created you go to the Pusher Dashboard and grab your application credentials from the already created "Azure" application.

pusher-api-access

Once I had the Pusher addon ready and my credentials I could jump into data scripts and so that any changes to the todo list could instantly be broadcast to anybody else viewing the list.

The code for this is unbelievably simple. The fact the insert, update and delete scripts are all separate makes things a bit repetitive, but ultimately you can broadcast the change events in just a few lines of code.

Broadcasting CRUD Trigger events

pusher-insert

The first thing that we do in the script is include the pusher-node-server library which Microsoft have made available because Pusher is in the Windows Azure Store.

We then create a new Pusher instance and provide it with our credentials.

After that we let the INSERT complete and if it is successful we trigger an event on a channel to broadcast that a new todo list item has been created. The first parameter here is the name of the channel, the second the name of the event (what happened) and the third is the data payload. You also need to wait for the request to complete in order for the item to have an id property.

Adding UPDATE and DELETE scripts were just as easy.

pusher-update

The item in the UPDATE script only has the changed properties. I had to modify my front-end JavaScript because of this.

pusher-delete

You only get the id of the item that was deleted in the DELETE do you need to create an object with an id property e.g. { id: 'some_id'}

Are the events being triggered

You can check to see if events are being triggered by using the existing application, which doe cause the scripts to be executed, and then view the Pusher Debug Console

pusher-debug-console

Making the front-end realtime

app.js relied quite heavily on a function called refreshTodoItems. Yuck! every time something happens in the application this function would query the Windows Azure Mobile data service to get all the new data. Why do this when you can just instantly push the changes to the client as they happen?!

If you'd prefer to read the code to see the changes you can do that via the "goodbye refresh, hello Pusher" commit which shows all the changes I made.

But, here are a few details.

The pusher-js script tag

A simple include:

pusher-js

Create a Pusher instance, subscribe and bind

You create a new Pusher instance and pass in your app_key. Doing this connects your app to Pusher.

You also identify that we're interested in changes to the todo list - you'll have seen that we were triggering on the todo channel in the mobile data services script.

For each type of event (insert, update and delete) that we expect on the channel and have a different function handle each of these.

pusher-instance-channels

Handle create events

When a new item is created we need to insert it into the existing list:

create-insert

The createItem function actually create a <li> and the insertItem function actually appends it to the view. We also reuse createItem function in the function that we renamed refreshTodoItems (Yuck!) to - initTodoItems. This means we only query the mobile service endpoint once when the app initial loads - Win!. Notice how many times I got to delete refreshTodoItems in the commit.

Handle update events

Because only the updated data is sent to the update handler this function is a bit bigger than I would have liked. We simply check to see what data is present in the update and then change the list as required:

update-item

Handle delete events

The delete event handler is passed an item with an id property. We simply find the <li> in the view with this id, slide it out of view and then remove it from the DOM.

delete-item

It's now realtime

If you now use the app, any time somebody else makes a change it'll instantly be broadcast to anybody else viewing the application.

Next, to deploy it to Windows Azure Web Sites

Windows Azure Web Sites

Creating a Windows Azure Web Site is a piece of cake!

create-website

In the following dialog make sure you check the "Publish from source control" checkbox. You can then choose to either sync with an existing github repo (very cool) or use a git repo and push to it. A nice simple tutorial on this can be found in the Publishing from Source Control to Windows Azure Web Sites guide.

create-publish-source

Add the remote repo locally using git remote add azure <repo_url>, then you can push to use using git push azure master. The Windows Azure portal actually updates straight away to show that the app has been deployed:

push-to-azure

The app is now live - or is it? It's GOTCHA time.

Gotchas

.js in root directory = node.js env detection

The first gotcha I came across was that it seem like the environment detection assumes your app is a Node.js app if you have a js file in the root directory. To get around this I had to move app.js to js/app.js.

Cross scheme and Origin (CORS) communication

Browsers implement rules that mean you can't communicate cross scheme: http <-> https. So, make sure that the app/web page and the assets (JavaScript) are all served from the same scheme.

One final thing you need to do is allow access from a given domain via the configuration for your mobile services. I came across this right at the end and nearly cried when I didn't think it was going to happen. But, unsurprisingly **the Gu* came to the rescue.

cors-config

Update

It would appear that CORS settings can get out of sync:

Tada - I mean TODO!

We no have a To Do list that multiple users can collaborate on and instantly see the changes as they happen. The back-end is powered by Windows Azure Mobile Services, the realtime communication is achieved using Pusher and the app/site is hosted on a Windows Azure Web Site.

Not bad for a few hours work whilst at Stacked13! What are you waiting for? Start playing with the realtime collaborative Windows Azure Mobile Service To Do app.