Also posted at Pivotal Labs
Second screen has been a buzzword for quite some time and rightfully so. Getting our tech gadgets to work as one has always been a desire. With the adoption of phones as the dominant personal computer over the last few years, we've naturally wanted to connect everything to them.
We're slowly implementing protocols and technologies such as WIDI, NFC and Bluetooth in the hopes of finding an all encompassing solution. So far, these solutions have been designed for communication over small distances, such as connecting to your car when it is nearby. What users really want, is to be connected to their world at all times regardless of distance.
Everything I've mentioned points to connecting one device to another. Second screen experiences shouldn't be limited to that. There is nothing stopping us from connecting a large number of devices together each playing their part in a unified experience.
Communication is getting cheaper and more reliable, devices are getting better access to the internet and better processing power. Applications are still being designed with the standard web/REST model in mind. The REST model is still valid and an important piece of the puzzle, but it can not solve the second screen paradigm alone.
We've all "Pushed" data to devices using services such as Urban Airship, Push Notifications on iOS or Google Cloud Messaging for Android. Most people accomplish pushing by using third party service because the technology these services have or the problems they have solved have seemed slightly out of our reach.
The ideal is to have your devices connected and receiving/sending messages to each other in real time. MQTT is an older protocol that has been used by industrial companies for years and more recently it is becoming a part of some of the software that you rely on the most, such as Blackberry Messenger. MQTT is a low cost messaging protocol that allows for persistent connections between a device and a server and is agnostic of the data you transfer. A low cost persistent connection and protocol make MQTT an ideal solution for real time communication in both directions.
AMQP is a message broker that runs on MQTT. AMQP offers rich features that help organize your connections and decide how messages get handled. The broker also gives a publish consume structure that is easy to use and understand.
RabbitMQ offers open sourced client and server implementation of AMQP. RabbitMQ comes in several languages and the community behind it offers implementations in several other languages. Their efforts make setting up an MQTT styled environment for your application simple and straightforward.
RabbitMQ offers some very convenient features such as guaranteeing delivery of messages and the ability to distribute server implementations. You can see an example of how Xtreme Labs has used RabbitMQ to connect devices for the Device Wall project.
We'll go into the finer details of each of these roles and their implementation principles. For now lets simply introduce the key pieces of the puzzle.
Each client device will have a specific role in the second screen experience. Most of these clients will need an AMQP connection. Some devices will not need to receive push notifications, these devices can omit the AMQP connection if they don't want to implement it.
This application resides in the cloud and connects to the AMQP server as any other client would. The Controller manages the state of the unified experience. It sends and receives messages from/to the clients and manages their unified state. It should also tie into the data that is being served up via REST, specifically the state data. The controller must be running at all times and always be connected to AMQP as this is the center of your experience.
The AMQP Server, or an MQTT implementation, will run in the cloud and handle all communication.
You will still need a REST server. It will work like a traditional REST/CRUD server, except the controller will be able to save state data into its databases so that the REST server can serve the larger chunks of data that define that state.
Building an application with a new type of communication will require you to rethink your usual architectural approach. It is important to understand why and when you need to send/receive data through AMQP and when to use REST.
The key difference between a second screen experience and a single screen experience is that the multiple screens offers a unified experience. Keeping them in sync requires real time communication. AMQP offers the real time communication required.
AMQP communication should be kept short and sweet. The information going through this channel will revolve around what state the user is in. In terms of second screen, the state should be related to what the collection of screens are doing in that moment. In the case of a game, if the users are waiting to start their game, they are in a waiting state and should all show a waiting room. Real time data such as the incoming messages from the other users also needs to come through on this channel.
Because the experience is split up across different devices, it is important to save all the state data on the server, the devices should no longer keep track of what screen they are on, to some degree. This allows the server to manage the experience.
The messages going through AMQP should be short and sweet, this ensures that the system as a whole isn't bogged down trying to transmit large data. Split your data appropriately between your REST server and your AMQP server. For example, do not transmit an entire document through AMQP, instead upload your document to the REST server and pass the url of the document via AMQP. In other words, try passing a minimum amount of information required via AMQP so that the application can build the state using the AMQP data and build the screen details using REST calls upon receiving a minimum amount of state information.
Using AMQP requires a constant connection to the AMQP server, as we all know devices such as our phone can seldom do that, especially as they move from connection to connection. With this concept of state being held on the server and real time information coming in at all times, losing connection means losing vital information to the user experience.
Regaining connection isn't as simple as with REST. Once you have reconnected, you need to "Fast Forward" to the right state. If you missed a message to start playing a game, you need to retrieve the missed message. Your REST server will need to be able to serve up the missed state data. In other words, the state of the Controller should be saved in the REST server in case clients need to recover from network failure, the Controller should only focus on the current state. The key point in all this is the order you perform actions to retrieve state. You must first regain a connection to AMQP and then ask the REST server for your state. This ensures that if the state changes between the time the server checks your state and sends it down, that your active AMQP connection will inform of this change and you can omit the information coming from REST.
While fast forwarding, it is up to you to figure out how to consolidate the incoming data. The easiest procedure is to ensure that only one data source is writing to your local state store at a time and launching events to let your UI know what it needs to do.
This architecture change is the main idea behind second screen experiences, it is important to understand each piece's role and how to best accomplish the task. As we move into the future we'll find more and more connected devices now have access to good internet connections and you'll find that a second screen experience will become more and more accessible.