Update (1 Feb 2011): I’ve shared some better sample code for Android
Last weekend, I went to Imperial College for Over The Air: a conference for mobile developers.
I gave a talk at the event on how to write a mobile application that uses push notifications. It was pretty well received, so I’d thought I’d share it here, too.
I’ve made some notes below to cover roughly what I said at the event. Any comments or questions (or corrections if you spot any!) are very welcome.
Update (24/10/2009): I revisited this presentation to address some of the feedback that I got on battery life implications of using MQTT.
The talk was intended as a developer’s workshop, with a number of code samples and walkthroughs.
It seemed safe to assume that an audience at Over The Air wouldn’t be afraid of looking at a little code!
As mobile data plans get more affordable, mobile developers are writing apps making more and more use of the network – relying on data on the Internet and from web services.
And the more we do this, the more we hammer our user’s batteries.
I didn’t want to labour this point at the event – for fear of trying to teach mobile developers how to suck eggs!
In many situations, for mobile apps which need to react to some data from a remote server, it is more efficient for changes to the data to be pushed to the mobile, rather than for the mobile to repeatedly poll the server.
Polling is generally an unsatisfactory compromise. Polling infrequently results in an application which can appear slow to respond to changes in the data – for example, polling every 30 minutes could potentially result in an application which takes 29 minutes before it notices the queried data has changed. Polling very frequently mitigates this, but at the cost of increasing the app’s battery usage.
It’s better for the mobile app to do neither – and simply wait for the server to tell it when the data changes.
They also use this as an alternative for any task which would otherwise require background threads – run as much code as you can on central servers where battery life is less of an issue, and have the server notify the mobile app when there is something to bring to the user’s attention.
Apple aren’t the only ones doing “push”, of course.
BlackBerry have been doing this for email for years, and they have an SDK which allows push notifications for other applications.
Vodafone’s betavine also offer a push notification API.
I think it uses an SMS-based approach, however I’ve not tried it for myself.
Alternatively, you can implement your own home-grown approach. Many mobile platforms allow you to intercept incoming SMS messages before the user sees them.
You can come up with a custom SMS data format that can be interpreted by your app, and this gives you simple push notification. However, the cost of sending SMS makes this an unpopular approach – you wouldn’t want to write an instant messaging client using SMS as a transport, for example!
My talk aimed to introduce developers at Over The Air to another approach: MQTT.
While it’s not necessarily ideal for every situation, my hope was that it would at least be new to my audience.
At a worst case, it’s another tool for their toolboxes – another approach to consider when they next need to implement a mobile application that might otherwise poll a server.
The obligatory disclaimer slide.
MQTT is a protocol created by my employer – IBM, and the approach outlined in my talk relies on server software available from IBM.
I wanted to be clear that this was not a sales pitch. I don’t work on commission – I’m a geek not a sales person, and have no interest in selling anything, particularly at a tech event like this.
Everything that I demonstrated can be downloaded for free. The MQTT specification is published and used by companies other than IBM.
As I have blogged before, I use MQTT for a lot of my own personal projects. I have an MQTT broker running in my house that I use for stuff like home energy monitoring. I use it because I think it’s good, and I wanted to share it for that reason.
MQTT is a lightweight way to connect multiple clients together: both mobiles and code running on servers.
Everything goes through a central message broker which is responsible for getting messages to and from the different clients.
To send a message, a client “publishes” it to the message broker.
The message broker delivers it to the correct client(s).
Publishing a message needs two things.
Payload : the data you want to send
And a topic.
This is how you address the message – by identifying what the message is about.
I used an example topic structure from a developerWorks article to explain how topics are hierarchical.
The “Topics” section of the article does a better job of explaining this than I probably did in my talk.
A client identifies what messages it wants to receive by “subscribing” to a topic.
For example, recalling the sample topic structure from my last slide, a client can subscribe to get updates about the arrival time of a specific flight flying into Heathrow.
If another client publishes an update with information about the arrival time of a different flight – our client will not get it.
We will only get messages published – in this case – with updates about flight 1024.
You don’t have to be so specific.
Wildcards are supported – either for a specific level of the topic tree structure, or for a whole subtree.
I gave an example of subscribing using wildcards.
For example, again referring back to the sample topic structure I showed, a client can subscribe to get updates about the arrival time of any flight for any airline coming into Heathrow
The first “+” is a wildcard for the airline name, and the second “+” is a wildcard for the flight number.
Or it could subscribe to receive any flight time updates for Heathrow – arrivals or departures, for any airline, for any flight number.
I think I may have been labouring the idea by this point!
Another example to demonstrate topic strings, this time translating twitter following into MQTT terminology.
You could subscribe to receive my tweets (“twitter/tweets/dalelane”), or everyone’s updates (“twitter/tweets/+”).
Topic strings are completely arbitrary – and as the developer, you can decide on how to structure your topic tree hierarchy.
A more complex topic tree could let you subscribe to only get my updates if I sent them from TweetDeck (“twitter/tweets/TweetDeck/dalelane”).
Or get anyone’s updates if they sent them from twhirl (“twitter/tweets/twhirl/+”).
Or get all of my updates regardless of what client I used (“twitter/tweets/+/dalelane”).
Or get everyone’s tweets regardless of client (“twitter/tweets/#”).
With the basics out of the way, I moved on to using MQTT for mobile.
First, a review of the traditional polling approach: a mobile app which polls something in “the cloud”.
With MQTT, you can move that polling to a server.
Let an app on the server (where you don’t care about battery life, etc.) poll the web service.
And use MQTT to push it to the mobile when it gets something of interest.
You end up with something like this.
The cogs represent the code you write – some of it lives on a server (probably the same server as your message broker) and polls the web service.
When it gets something different back from the cloud web service, it publishes it to the message broker.
Your mobile app can choose which updates of interest it receives from the broker.
Your code – both server code and your mobile app – uses MQTT to communicate with the message broker.
And the server code is free to query the cloud however you want.
The point is that we’ve moved polling to the connection between the web service and your server code – where battery life is not as expensive.
That was more than enough theory.
Time to walk through an example app: an MQTT Hello World.
First, you need the message broker software to run on the server.
You can download one for free from IBM alphaWorks.
What you get is a zip file with versions of the server software for a variety of platforms, including the obvious (Windows, Red Hat, Ubuntu, Mac OS, etc.).
It is very configurable, but for now, you can just run the executable – and the server is running.
As a quick aside, I highlighted that the server output on the previous slide showed that the server was listening on port 1883.
This is the assigned port number for the MQTT protocol, which is why it is used by default.
You can change this if you want to use a different port number.
Now we need an MQTT client – something to send and receive (to publish and subscribe) messages to the broker.
The Java client is an easy place to start.
Again, you can download it from an IBM site.
The zip file you download includes a jar with a sample Java client.
Just run the sample jar …
… and you get a little GUI utility app
For my first code-free example, I used two clients, so that I could send and receive messages.
First thing I did was give each client a unique name.
Imaginatively, I used “client1″ and “client2″.
Once that’s done, I clicked “Connect” on each GUI.
The server output showed the connection of each client.
Note that you need to specify the address and port number, but I just left the localhost:1883 defaults for this demonstration.
For my first example:
On client1, I subscribed to “dalelane/hello/world” by entering the topic name and clicking Subscribe.
On client2, I published a message by entering the topic, and the message payload and clicking Publish.
The message was received by the first client and displayed here.
We sent our first message.
I also demonstrated wildcards, using the client GUIs to subscribe to “hello/#” and then publish to any topic string that starts with “hello/”.
I also highlighted that I could subscribe to as many topics (with or without wildcards) as I wanted.
The GUI is good for learning, practising and testing. But it is obviously more interesting to try doing it yourself from code.
The Java client zip I downloaded earlier includes a smaller client library.
I used this to give a walkthrough of a simple Java application that I wrote for my presentation.
The same three operations apply : connect, publish, subscribe.
First, I need to connect to the message broker. I went through the couple of lines of code necessary to do this, highlighting where you provide the hostname, port number and unique client id, as I did before using the test GUI.
To publish a message, you just call the publish method, giving it the two bits of information I mentioned before: the topic and the payload.
The payload needs to be in bytes, so I just got the bytes from the test string my sample app published.
To subscribe to receive messages, there are a couple of things that you need to do first.
Firstly, you need to implement one of the MQTT callback interfaces. I used the simple one, “MqttSimpleCallback”, for my sample.
Secondly, I registered to receive call backs from the MQTT client library.
Once we’ve done this, we can subscribe to a topic string.
I showed how the code allows this, and highlighted again that you can subscribe to multiple topics – either in a single subscribe() call, or by making multiple calls to the subscribe method.
I demonstrated using Java because it’s a nice, easy start.
But I explained that you can do the same from other languages if you prefer.
As I noted in my talk, not all of the client libraries I mentioned have been produced by IBM. The MQTT spec is published, so some developers have implemented client libraries in their language-of-choice and shared it with the community.
As a result, I cannot comment on the quality and/or completeness of some of the implementations.
The point remains, however, that you have a lot of choice as a developer in how to use MQTT.
The Java client library runs on many mobile platforms.
For example, Android.
To support any possible overnight hacks, I created a “Hello World” project for doing this MQTT stuff from an Android phone.
I don’t have slides to walkthrough my sample Android code, but I shared both the source code for the Android app as a zipped Eclipse project, and the compiled, installable Android application.
As I mentioned at the time, it’s important to note that this was the first Android app I’d ever written.
I shared this as an example of how to do MQTT, not a sample of how to write an Android app. For all I know, as an Android app, it’s garbage!
(Although, that said, it seems to work okay.)
And here is my sample app running, with buttons to connect / disconnect to a message broker, subscribe / unsubscribe to message topics and publish messages.
I used the sample Java MQTT GUI on my desktop as before, but this time to publish messages to and from my Android phone.
That was pretty much the end of my how-to talk.
I used the rest of my time to go through some examples of what could be done with push notifications to mobiles using MQTT.
To start with, twitter.
Each of the twitter clients I have on my mobile phones poll twitter for new tweets. Typically, they let the user specify how often they should poll. Poll very often and you can drain your battery in hours. Poll infrequently, and you might not receive a message for quite a while.
Why not poll twitter as frequently as you like from a server app?
Then use MQTT to push the tweets I’m interested in to my phone.
The twitter API is simple enough that I threw together a quick test app for my talk that could be run on a server.
It polls twitter.com and republishes tweets or replies I receive to the message broker.
I demonstrated how I can subscribe to receive these published tweets on my Android MQTT app.
As I mentioned while I talked about topic structures before, clients can as selective or as general as they want when they subscribe.
In this slide, I showed a client subscribed to get everyone’s tweets. More usefully, you could only subscribe to get tweets from a particular subset of the people you follow.
This would mean more than just not displaying tweets from other people you follow.
When you subscribe you tell the message broker which messages you want to receive. It wont send you anything else. (And you’re not polling needlessly in the meantime.)
If you subscribed to get tweets from a single person, you’d only pay the network and battery life hit on the mobile when they actually tweeted. (Even if the server app is needlessly polling every minute.)
My sample Android app isn’t very pretty, and this isn’t something you’d put in front of a user as a Twitter application.
But even now – after just a couple of hundred lines of code – we’ve got something very powerful.
Other things we’ve done using MQTT for mobile include apps like this: applications which let a user specify information that they want to be informed about.
If the specified information changes, this is pushed to the mobile app immediately. Each update also includes information about what the user can request in response.
The simple example shown in my talk was getting updates if the lamp in our office is on or off. In response, a user can remotely switch the lamp on (if it’s off) or off (if it’s on).
Other examples include allowing users in an office environment to subscribe to receive notifications relevant to the office where they are working.
This could be subscribing to receive fire alarms or other emergency notifications to their mobile – particularly useful for deaf users who might not hear a conventional fire alarm.
This is also a good example of situations where polling is not good enough. With something like a fire alarm, you want the mobile to receive the message immediately. You can’t afford to wait for a mobile app which polls every 30 minutes for example.
I shared a few more links about what I talked about. And that was it.
I was pleased that the talk sparked a lot of questions and discussion.
There were several questions about the difference between MQTT and other technologies such as XMPP, SIP, and pubsubhubbub.
I was also pleased to have a couple of guys from Ericsson who talked about their Mobile Java Push API. They also had some interesting material to share, such as a graph showing the relative battery impact of different polling periods vs their push API.
I hope people found the talk useful. I was certainly aware of a number of people who downloaded a message broker and client to give it a try for themselves, which I guess is a good sign!
As I said after my talk, if anyone has any questions about doing mobile push notifications using MQTT, please do feel free to get in touch.