1page.title=GCM Cloud Connection Server 2@jd:body 3 4<div id="qv-wrapper"> 5<div id="qv"> 6 7<h2>Quickview</h2> 8 9<ul> 10<li>Get an introduction to key CCS terms and concepts.</li> 11<li>Learn how to send and receive both upstream and downstream messages in CCS.</li> 12</ul> 13 14 15<h2>In this document</h2> 16 17<ol class="toc"> 18 <li><a href="#gcm">CCS vs. GCM HTTP</a> </li> 19 <li><a href="#usage">How to Use CCS</a> 20 <ol> 21 <li><a href="#send_msg">Sending Messages</a></li> 22 <li><a href="#format">Message Format</a></li> 23 <li><a href="#msg_examples">Message Examples</a></li> 24 </ol> 25 </li> 26 <li><a href="#flow">Control Flow</a> </li> 27</ol> 28 29<h2>See Also</h2> 30 31<ol class="toc"> 32<li><a href="{@docRoot}google/play-services/gcm/gs.html">Getting Started</a></li> 33<li><a href="https://services.google.com/fb/forms/gcm/" class="external-link" target="_android">CCS and User Notifications Signup Form</a></li> 34</ol> 35 36</div> 37</div> 38 39<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> 40 41<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> 42<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> 43<ul> 44 <li>The asynchronous nature of XMPP allows you to send more messages with fewer resources.</li> 45 <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> 46<li>You can send messages back using the same connection used for receiving, thereby improving battery life.</li> 47</ul> 48 49<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> 50 51<h2 id="gcm">CCS vs. GCM HTTP</h2> 52 53<p>CCS messaging differs from GCM HTTP messaging in the following ways:</p> 54<ul> 55 <li>Upstream/Downstream messages 56 <ul> 57 <li>GCM HTTP: Downstream only: cloud-to-device. </li> 58 <li>CCS: Upstream and downstream (device-to-cloud, cloud-to-device). </li> 59 </ul> 60 </li> 61 <li>Asynchronous messaging 62 <ul> 63 <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> 64 <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> 65 </ul> 66 </li> 67 68 <li>JSON 69 <ul> 70 <li>GCM HTTP: JSON messages sent as HTTP POST.</li> 71 <li>CCS: JSON messages encapsulated in XMPP messages.</li> 72 </ul> 73 </li> 74</ul> 75<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> 76 77<h2 id="usage">How to Use CCS</h2> 78 79<p>GCM Cloud Connection Server (CCS) is an XMPP endpoint, running on {@code http://gcm.googleapis.com} port 5235.</p> 80 81<p>CCS requires a Transport Layer Security (TLS) connection. That means the XMPP client must initiate a TLS connection. 82For example in smack, you would call {@code setSocketFactory(SSLSocketFactory)}, similar to “old style SSL” XMPP connections and https.</p> 83 84<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> 85 86<p> You can use most XMPP libraries to interact with CCS.</p> 87 88<h3 id="send_msg">Sending messages</h3> 89 90<p>The following snippets illustrate how to perform authentication in CCS.</p> 91<h4>Client</h4> 92<pre><stream:stream to="gcm.googleapis.com" 93 version="1.0" xmlns="jabber:client" 94 xmlns:stream="http://etherx.jabber.org/streams"/> 95</pre> 96<h4>Server</h4> 97<pre><str:features xmlns:str="http://etherx.jabber.org/streams"> 98 <mechanisms xmlns="urn:ietf:params:xml:ns:xmpp-sasl"> 99 <mechanism>X-OAUTH2</mechanism> 100 <mechanism>X-GOOGLE-TOKEN</mechanism> 101 <mechanism>PLAIN</mechanism> 102 </mechanisms> 103</str:features> 104</pre> 105 106<h4>Client</h4> 107<pre><auth mechanism="PLAIN" 108xmlns="urn:ietf:params:xml:ns:xmpp-sasl">MTI2MjAwMzQ3OTMzQHByb2plY3RzLmdjbS5hb 109mRyb2lkLmNvbQAxMjYyMDAzNDc5FzNAcHJvamVjdHMtZ2EtLmFuZHJvaWQuY29tAEFJe 110mFTeUIzcmNaTmtmbnFLZEZiOW1oekNCaVlwT1JEQTJKV1d0dw==</auth> 111</pre> 112<h4>Server</h4> 113<pre><success xmlns="urn:ietf:params:xml:ns:xmpp-sasl"/></pre> 114 115<h3 id="format">Message Format</h3> 116<p>CCS uses normal XMPP <code><message></code> stanzas. The body of the message must be: 117</p> 118<pre> 119<gcm xmlns:google:mobile:data> 120 <em>JSON payload</em> 121</gcm> 122</pre> 123 124<p>The JSON payload for server-to-device is similar to what the GCM http endpoint uses, with these exceptions:</p> 125<ul> 126 <li>There is no support for multiple recipients.</li> 127 <li>{@code to} is used instead of {@code registration_ids}.</li> 128 <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> 129 130 <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: 131 132<pre>message_type = ('ack' OR 'nack');</pre> 133 </li> 134</ul> 135<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. 136</p> 137<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. 138</p> 139 140<h3 id="msg_examples">Message Examples</h3> 141 142<p>Here is an XMPP stanza containing the JSON message from a 3rd-party server to CCS: 143 144</p> 145<pre><message id=""> 146 <gcm xmlns="google:mobile:data"> 147 { 148 "to":"REGISTRATION_ID", // "to" replaces "registration_ids" 149 "message_id":"m-1366082849205" // new required field 150 "data": 151 { 152 "hello":"world", 153 } 154 "time_to_live":"600", 155 "delay_while_idle": true/false 156 } 157 </gcm> 158</message> 159</pre> 160 161<p>Here is an XMPP stanza containing the ACK/NACK message from CCS to 3rd-party server: 162</p> 163<pre><message id=""> 164 <gcm xmlns="google:mobile:data"> 165 { 166 "from":"REGID", 167 "message_id":"m-1366082849205" 168 "message_type":"ack" 169 } 170 </gcm> 171</message> 172 173<message id=""> 174 <gcm xmlns="google:mobile:data"> 175 { 176 "from":"REGID", 177 "message_id":"m-1366082849205" 178 "error": ERROR_CODE, 179 "message_type":"nack" 180 } 181 </gcm> 182</message> 183</pre> 184 185<h4>Upstream Messages</h4> 186 187<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> 188 189<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> 190 191<pre>GoogleCloudMessaging gcm = GoogleCloudMessaging.get(context); 192String GCM_SENDER_ID = "Your-Sender-ID"; 193AtomicInteger msgId = new AtomicInteger(); 194String id = Integer.toString(msgId.incrementAndGet()); 195Bundle data = new Bundle(); 196// Bundle data consists of a key-value pair 197data.putString("hello", "world"); 198// "time to live" parameter 199int ttl = [0 seconds, 4 weeks] 200 201gcm.send(GCM_SENDER_ID + "@gcm.googleapis.com", id, ttl, data); 202</pre> 203 204<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> 205 206<pre><message id=""> 207 <gcm xmlns="google:mobile:data"> 208 { 209 "category":"com.example.yourapp", // to know which app sent it 210 "data": 211 { 212 "hello":"world", 213 }, 214 "message_id":"m-123", 215 "from":"REGID" 216 } 217 </gcm> 218</message></pre> 219 220<p>Here is the format of the ACK expected by CCS from 3rd-party servers in response to the above message:</p> 221 222<pre><message id=""> 223 <gcm xmlns="google:mobile:data"> 224 { 225 "to":"REGID", 226 "message_id":"m-123" 227 "message_type":"ack" 228 } 229 </gcm> 230</message></pre> 231 232<h4 id="python">Python Example</h4> 233<p>This example illustrates how to connect, 234send, and receive GCM messages using XMPP. It shouldn't be used as-is 235on a production deployment.</p> 236 237<pre> 238import sys, json, xmpp 239SERVER = ('gcm.googleapis.com', 5235) 240#USERNAME = '<your_numeric_project_id>' 241#PASSWORD = '<your_gcm_api_key>' 242 243# Unique message id for downstream messages 244sent_message_id = 0 245 246def message_callback(session, message): 247 global sent_message_id 248 gcm = message.getTags('gcm') 249 250 if gcm: 251 gcm_json = gcm[0].getData() 252 msg = json.loads(gcm_json) 253 msg_id = msg['message_id'] 254 device_reg_id = msg['from'] 255 256 # Ignore non-standard messages (e.g. acks/nacks). 257 if not msg.has_key('message_type'): 258 # Acknowledge the incoming message. 259 send({'to': device_reg_id, 260 'message_type': 'ack', 261 'message_id': msg_id}) 262 263 # Send a response back to the server. 264 send({'to': device_reg_id, 265 'message_id' : str(sent_message_id), 266 'data': {'pong': 1}}) 267 sent_message_id = sent_message_id + 1 268 269def send(json_dict): 270 template = ("<message from='{0}' to='gcm@google.com'>" 271 "<gcm xmlns='google:mobile:data'>{1}</gcm></message>") 272 client.send(xmpp.protocol.Message( 273 node=template.format(client.Bind.bound[0], 274 json.dumps(json_dict)))) 275 276client = xmpp.Client(SERVER[0], debug=['socket']) 277client.connect(server=SERVER, secure=1, use_srv=False) 278auth = client.auth(USERNAME, PASSWORD, 'test') 279if not auth: 280 print 'Authentication failed!' 281 sys.exit(1) 282 283client.RegisterHandler('message', message_callback) 284 285while True: 286 client.Process(1)</pre> 287 288<h2 id="flow">Control Flow</h2> 289 290<p>Every message sent by a 3rd-party server to CCS receives either an ACK or a NACK response. A single connection can have at most 1000 messages that were sent without having yet received a response.</p> 291 292<p>To enforce this policy, the app can maintain a counter of sent messages that increments on each send and decrements on each ACK or NACK. If the counter exceeds 1000, the app should stop sending messages until an ACK or NACK is received.</p> 293 294<p>Conversely, when CCS sends messages to a 3rd-party server, it expects ACKs for each message it sends, and it will not send more than 1000 unacknowledged messages.</p> 295 296<p>The ACKs and messages must match on each connection. You can only send an ACK for a message on the connection on which it was received.</p> 297 298