| page.title=GCM Cloud Connection Server |
| @jd:body |
| |
| <div id="qv-wrapper"> |
| <div id="qv"> |
| |
| <h2>Quickview</h2> |
| |
| <ul> |
| <li>Get an introduction to key CCS terms and concepts.</li> |
| <li>Learn how to send and receive both upstream and downstream messages in CCS.</li> |
| </ul> |
| |
| |
| <h2>In this document</h2> |
| |
| <ol class="toc"> |
| <li><a href="#gcm">CCS vs. GCM HTTP</a> </li> |
| <li><a href="#usage">How to Use CCS</a> |
| <ol> |
| <li><a href="#send_msg">Sending Messages</a></li> |
| <li><a href="#format">Message Format</a></li> |
| <li><a href="#msg_examples">Message Examples</a></li> |
| </ol> |
| </li> |
| <li><a href="#flow">Flow Control</a> </li> |
| </ol> |
| |
| <h2>See Also</h2> |
| |
| <ol class="toc"> |
| <li><a href="{@docRoot}google/play-services/gcm/gs.html">Getting Started</a></li> |
| <li><a href="https://services.google.com/fb/forms/gcm/" class="external-link" target="_android">CCS and User Notifications Signup Form</a></li> |
| </ol> |
| |
| </div> |
| </div> |
| |
| <p class="note"><strong>Note:</strong> To try out this feature, sign up using <a href="https://services.google.com/fb/forms/gcm/">this form</a>.</p> |
| |
| <p>The GCM Cloud Connection Server (CCS) allows third party 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.</p> |
| <p>You can continue to use the HTTP request mechanism to send messages to GCM servers, side-by-side with CCS which uses XMPP. Some of the benefits of CCS include:</p> |
| <ul> |
| <li>The asynchronous nature of XMPP allows you to send more messages with fewer resources.</li> |
| <li>Communication is bidirectional—not only can the server send messages to the device, but the device can send messages back to the server.</li> |
| <li>You can send messages back using the same connection used for receiving, thereby improving battery life.</li> |
| </ul> |
| |
| <p>The upstream messaging (device-to-cloud) feature of CCS is part of the Google Play services platform. Upstream messaging is available through the <a href="{@docRoot}reference/com/google/android/gms/gcm/GoogleCloudMessaging.html">{@code GoogleCloudMessaging}</a> APIs. To use upstream messaging and the new streamlined registration process, you must <a href="{@docRoot}google/play-services/setup.html">set up</a> the Google Play services SDK.</p> |
| |
| <p class="note"><strong>Note:</strong> For an example of an XMPP server, see <a href="server.html#xmpp">GCM Server</a>. |
| |
| <h2 id="gcm">CCS vs. GCM HTTP</h2> |
| |
| <p>CCS messaging differs from GCM HTTP messaging in the following ways:</p> |
| <ul> |
| <li>Upstream/Downstream messages |
| <ul> |
| <li>GCM HTTP: Downstream only: cloud-to-device. </li> |
| <li>CCS: Upstream and downstream (device-to-cloud, cloud-to-device). </li> |
| </ul> |
| </li> |
| <li>Asynchronous messaging |
| <ul> |
| <li>GCM HTTP: 3rd-party servers send messages as HTTP POST requests and wait for a response. This mechanism is synchronous and causes the sender to block before sending another message.</li> |
| <li>CCS: 3rd-party servers connect to Google infrastructure using a persistent XMPP connection and send/receive messages to/from all their devices at full line speed. CCS sends acknowledgements or failure notifications (in the form of special ACK and NACK JSON-encoded XMPP messages) asynchronously.</li> |
| </ul> |
| </li> |
| |
| <li>JSON |
| <ul> |
| <li>GCM HTTP: JSON messages sent as HTTP POST.</li> |
| <li>CCS: JSON messages encapsulated in XMPP messages.</li> |
| </ul> |
| </li> |
| </ul> |
| <p>This document describes how to use CCS. For general concepts and information on how to use GCM HTTP, see the <a href="gcm.html">GCM Architectural Overview</a>.</p> |
| |
| <h2 id="usage">How to Use CCS</h2> |
| |
| <p>GCM Cloud Connection Server (CCS) is an XMPP endpoint, running on {@code http://gcm.googleapis.com} port 5235.</p> |
| |
| <p>CCS requires a Transport Layer Security (TLS) connection. That means the XMPP client must initiate a TLS connection. |
| For example in smack, you would call {@code setSocketFactory(SSLSocketFactory)}, similar to “old style SSL” XMPP connections and https.</p> |
| |
| <p>CCS requires a SASL PLAIN authentication mechanism using {@code <your_GCM_Sender_Id>@gcm.googleapis.com} (GCM sender ID) and the API key as the password, where the sender ID and API key are the same as described in <a href="gs.html">Getting Started</a>.</p> |
| |
| <p> You can use most XMPP libraries to interact with CCS.</p> |
| |
| <h3 id="send_msg">Sending messages</h3> |
| |
| <p>The following snippets illustrate how to perform authentication in CCS.</p> |
| <h4>Client</h4> |
| <pre><stream:stream to="gcm.googleapis.com" |
| version="1.0" xmlns="jabber:client" |
| xmlns:stream="http://etherx.jabber.org/streams"/> |
| </pre> |
| <h4>Server</h4> |
| <pre><str:features xmlns:str="http://etherx.jabber.org/streams"> |
| <mechanisms xmlns="urn:ietf:params:xml:ns:xmpp-sasl"> |
| <mechanism>X-OAUTH2</mechanism> |
| <mechanism>X-GOOGLE-TOKEN</mechanism> |
| <mechanism>PLAIN</mechanism> |
| </mechanisms> |
| </str:features> |
| </pre> |
| |
| <h4>Client</h4> |
| <pre><auth mechanism="PLAIN" |
| xmlns="urn:ietf:params:xml:ns:xmpp-sasl">MTI2MjAwMzQ3OTMzQHByb2plY3RzLmdjbS5hb |
| mRyb2lkLmNvbQAxMjYyMDAzNDc5FzNAcHJvamVjdHMtZ2EtLmFuZHJvaWQuY29tAEFJe |
| mFTeUIzcmNaTmtmbnFLZEZiOW1oekNCaVlwT1JEQTJKV1d0dw==</auth> |
| </pre> |
| <h4>Server</h4> |
| <pre><success xmlns="urn:ietf:params:xml:ns:xmpp-sasl"/></pre> |
| |
| <h3 id="format">Message Format</h3> |
| <p>CCS uses normal XMPP <code><message></code> stanzas. The body of the message must be: |
| </p> |
| <pre> |
| <gcm xmlns:google:mobile:data> |
| <em>JSON payload</em> |
| </gcm> |
| </pre> |
| |
| <p>The JSON payload for server-to-device is similar to what the GCM http endpoint uses, with these exceptions:</p> |
| <ul> |
| <li>There is no support for multiple recipients.</li> |
| <li>{@code to} is used instead of {@code registration_ids}.</li> |
| <li>CCS adds the field {@code message_id}, which is required. This ID uniquely identifies the message in an XMPP connection. The ACK or NACK from CCS uses the {@code message_id} to identify a message sent from 3rd-party servers to CCS. Therefore, it's important that this {@code message_id} not only be unique, but always present.</li> |
| |
| <li>For ACK/NACK messages that are special control messages, you also need to include a {@code message_type} field in the JSON message. For example: |
| |
| <pre>message_type = ('ack' OR 'nack');</pre> |
| </li> |
| </ul> |
| <p>For each message a device sends to the server, you need to send an ACK message. You never need to send a NACK message. If you don't send an ACK for a message, CCS will just resend it. |
| </p> |
| <p>CCS also sends an ACK or NACK for each server-to-device message. If you do not receive either, it means that the TCP connection was closed in the middle of the operation and your server needs to resend the messages. |
| </p> |
| |
| <h3 id="msg_examples">Message Examples</h3> |
| |
| <p>Here is an XMPP stanza containing the JSON message from a 3rd-party server to CCS: |
| |
| </p> |
| <pre><message id=""> |
| <gcm xmlns="google:mobile:data"> |
| { |
| "to":"REGISTRATION_ID", // "to" replaces "registration_ids" |
| "message_id":"m-1366082849205" // new required field |
| "data": |
| { |
| "hello":"world", |
| } |
| "time_to_live":"600", |
| "delay_while_idle": true/false |
| } |
| </gcm> |
| </message> |
| </pre> |
| |
| <p>Here is an XMPP stanza containing the ACK/NACK message from CCS to 3rd-party server: |
| </p> |
| <pre><message id=""> |
| <gcm xmlns="google:mobile:data"> |
| { |
| "from":"REGID", |
| "message_id":"m-1366082849205" |
| "message_type":"ack" |
| } |
| </gcm> |
| </message> |
| |
| <message id=""> |
| <gcm xmlns="google:mobile:data"> |
| { |
| "from":"REGID", |
| "message_id":"m-1366082849205" |
| "error": ERROR_CODE, |
| "message_type":"nack" |
| } |
| </gcm> |
| </message> |
| </pre> |
| |
| <h4>Upstream Messages</h4> |
| |
| <p>Using CCS and the <a href="{@docRoot}reference/com/google/android/gms/gcm/GoogleCloudMessaging.html">GoogleCloudMessaging</a> API, you can send messages from a user's device to the cloud.</p> |
| |
| <p>Here is how you send an upstream message using the <a href="{@docRoot}reference/com/google/android/gms/gcm/GoogleCloudMessaging.html">GoogleCloudMessaging</a> API. For a complete example, see <a href="gs.html#gs_example">Getting Started</a>:</p> |
| |
| <pre>GoogleCloudMessaging gcm = GoogleCloudMessaging.get(context); |
| String GCM_SENDER_ID = "Your-Sender-ID"; |
| AtomicInteger msgId = new AtomicInteger(); |
| String id = Integer.toString(msgId.incrementAndGet()); |
| Bundle data = new Bundle(); |
| // Bundle data consists of a key-value pair |
| data.putString("hello", "world"); |
| // "time to live" parameter |
| int ttl = [0 seconds, 4 weeks] |
| |
| gcm.send(GCM_SENDER_ID + "@gcm.googleapis.com", id, ttl, data); |
| </pre> |
| |
| <p>This call generates the necessary XMPP stanza for sending the upstream message. The message goes from the app on the device to CCS to the 3rd-party server. The stanza has the following format:</p> |
| |
| <pre><message id=""> |
| <gcm xmlns="google:mobile:data"> |
| { |
| "category":"com.example.yourapp", // to know which app sent it |
| "data": |
| { |
| "hello":"world", |
| }, |
| "message_id":"m-123", |
| "from":"REGID" |
| } |
| </gcm> |
| </message></pre> |
| |
| <p>Here is the format of the ACK expected by CCS from 3rd-party servers in response to the above message:</p> |
| |
| <pre><message id=""> |
| <gcm xmlns="google:mobile:data"> |
| { |
| "to":"REGID", |
| "message_id":"m-123" |
| "message_type":"ack" |
| } |
| </gcm> |
| </message></pre> |
| |
| |
| <h2 id="flow">Flow Control</h2> |
| |
| <p>Every message sent to CCS receives either an ACK or a NACK response. Messages that haven't received one of these responses are considered pending. If the pending message count reaches 1000, the 3rd-party server should stop sending new messages and wait for CCS to acknowledge some of the existing pending messages.</p> |
| |
| <p>Conversely, to avoid overloading the 3rd-party server, CCS will stop sending if there are too many unacknowledged messages. Therefore, the 3rd-party server should "ACK" received messages as soon as possible to maintain a constant flow of incoming messages. The aforementioned pending message limit doesn't apply to these ACKs. Even if the pending message count reaches 1000, the 3rd-party server should continue sending ACKs to avoid blocking delivery of new messages.</p> |
| |
| <p>ACKs are only valid within the context of one connection. If the connection is closed before a message can be ACKed, the 3rd-party server should wait for CCS to resend the message before ACKing it again. |
| </p> |
| |