Sunday, 25 August 2013

API for communicating through CCS (Google Cloud Messaging)

About CCS:

The GCM Cloud Connection Server (CCS) is a connection server based on XMPP, offering a new option to the old HTTP request mechanism to send messages to GCM servers. CCS allows 3rd-party app servers to communicate with Android devices by establishing a persistent TCP connection with Google servers using the XMPP protocol. This communication is asynchronous and bidirectional.
CCS offers some important benefits:
- The asynchronous nature of XMPP allows you to send more messages with fewer resources.
- Communication is bidirectional, not only can the server send messages to the device, but the device can send messages back to the server.
- You can send messages back using the same connection used for receiving, thereby improving battery life.

The format of CCS messages continue with the same general structure than with the GCM HTTP request mecanism.

(Information taken from: [4])

Api for communicating through CCS:

I developed an API for communicating through CCS ([1]). For this, I designed a way of building the messages, sending them and handling the result.
For efficiently sending/receiving messages without blocking a connection, I decided to communicate with CCS server through a worker thread which maintains a XMPP connection and handles the ack/nack protocol of messages. So you have to start this worker thread before sending notifications, and then communicate with it through a channel. Also, it is possible to define a callback function to be called each time a message arrives from devices.
For dealing with XMPP connections, I opted to use the Pontarius XMPP library, which has a very friendly interface. I want to specially thank to Pontarius mantainers for their quick response to my issues using this library.
So, the API looks like this:
startCCS :: GCMAppConfig              -- Main configuration for the GCM service.
         -> (RegId -> Value -> IO ()) -- Callback function to be called each time
                                      -- a message arrives from a device.
         -> IO CCSManager

closeCCS :: CCSManager -> IO ()

sendCCS  :: CCSManager -> GCMmessage -> IO GCMresult

The main idea is: -  First of all, the sevice is started with: 'startCCS'.
    This function:
     *  Creates a channel to put the notifications to be sent.
     *  Starts a worker thread, which maintains a XMPP connection with CCS servers, sends the data it receives through the cannel, handle the ack/nack protocol of messages and everytime it receives a message from devices, it will call the callback function.
     *  Returns a CCSManager.

 - Then, I can use 'sendCCS' to send messages.
    Every time I call it:
     *  It puts the message on the channel.
     *  Wait until the time the message is taken by the worker thread.
     *  When the message is taken from the channel, the worker thread will send me a duplicate copy of the error channel. So, I will wait for the end of the sending, or an error msg through the error channel.
     *  I return the appropiate result depending on a successful or not operation.

 - I stop the service with 'closeCCS'. It kills the worker thread.

The worker identifies each message it sends with a number, which is sent to CCS. This number is returned in nack/ack messages by the CCS servers, so it can know if it was successfully sent and returns a proper result.
The code is available on GitHub:
 The CCS Api : [1]
 Test example for CCS: [2]
 - Android App for CCS: [3]

For more information about:
 The CCS Service: [4]