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
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.
Once the addon has been created you go to the Pusher Dashboard and grab your application credentials from the already created "Azure" application.
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.
<h3 id=”broadcasting-c<span-style=”text-decoration:-line-through;”>r</span>ud-trigger-events”><a href=”#broadcasting-c<span-style=”text-decoration:-line-through;”>r</span>ud-trigger-events”>Broadcasting CRUD Trigger events</a></h3>
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.
The item
in the UPDATE
script only has the changed properties. I had to modify my front-end JavaScript because of this.
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
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:
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.
Handle create events
When a new item is created we need to insert it into the existing list:
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:
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.
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!
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.
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:
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.
Update
It would appear that CORS settings can get out of sync:
Just noticed the the CORS settings for an #Azure #MobileServices app got out of sync. CORS wasn't working so I had to edit & save to re-sync
— Phil Leggetter (@leggetter) April 14, 2013
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.