summaryrefslogtreecommitdiffstats
path: root/docs/html/google/gcm/ccs.jd
blob: 0cadbd245c16bc1d18a3ee4ca62791d3b744d10a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
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&mdash;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 &lt;your_GCM_Sender_Id&gt;&#64;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>&lt;stream:stream to=&quot;gcm.googleapis.com&quot; 
        version=&quot;1.0&quot; xmlns=&quot;jabber:client&quot; 
        xmlns:stream=&quot;http://etherx.jabber.org/streams&quot;/&gt;
</pre>
<h4>Server</h4>
<pre>&lt;str:features xmlns:str=&quot;http://etherx.jabber.org/streams&quot;&gt;
 &lt;mechanisms xmlns=&quot;urn:ietf:params:xml:ns:xmpp-sasl&quot;&gt;
   &lt;mechanism&gt;X-OAUTH2&lt;/mechanism&gt;
   &lt;mechanism&gt;X-GOOGLE-TOKEN&lt;/mechanism&gt;
   &lt;mechanism&gt;PLAIN&lt;/mechanism&gt;
 &lt;/mechanisms&gt;
&lt;/str:features&gt;
</pre>

<h4>Client</h4>
<pre>&lt;auth mechanism=&quot;PLAIN&quot;
xmlns=&quot;urn:ietf:params:xml:ns:xmpp-sasl&quot;&gt;MTI2MjAwMzQ3OTMzQHByb2plY3RzLmdjbS5hb
mRyb2lkLmNvbQAxMjYyMDAzNDc5FzNAcHJvamVjdHMtZ2EtLmFuZHJvaWQuY29tAEFJe
mFTeUIzcmNaTmtmbnFLZEZiOW1oekNCaVlwT1JEQTJKV1d0dw==&lt;/auth&gt;
</pre>
<h4>Server</h4>
<pre>&lt;success xmlns=&quot;urn:ietf:params:xml:ns:xmpp-sasl&quot;/&gt;</pre>

<h3 id="format">Message Format</h3>
<p>CCS uses normal XMPP <code>&lt;message&gt;</code> stanzas. The body of the message must be:
</p>
<pre>
&lt;gcm xmlns:google:mobile:data&gt;
    <em>JSON payload</em>
&lt;/gcm&gt;
</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>&lt;message id=&quot;&quot;&gt;
  &lt;gcm xmlns=&quot;google:mobile:data&quot;&gt;
  {
      &quot;to&quot;:&quot;REGISTRATION_ID&quot;,  // &quot;to&quot; replaces &quot;registration_ids&quot;
      &quot;message_id&quot;:&quot;m-1366082849205&quot; // new required field
      &quot;data&quot;:
      {
          &quot;hello&quot;:&quot;world&quot;,
      }
      &quot;time_to_live&quot;:&quot;600&quot;,
      &quot;delay_while_idle&quot;: true/false
  }
  &lt;/gcm&gt;
&lt;/message&gt;
</pre>

<p>Here is an XMPP stanza containing the ACK/NACK message from CCS to 3rd-party server:
</p>
<pre>&lt;message id=&quot;&quot;&gt;
  &lt;gcm xmlns=&quot;google:mobile:data&quot;&gt;
  {
      &quot;from&quot;:&quot;REGID&quot;,
      &quot;message_id&quot;:&quot;m-1366082849205&quot;
      &quot;message_type&quot;:&quot;ack&quot;
  }
  &lt;/gcm&gt;
&lt;/message&gt;

&lt;message id=&quot;&quot;&gt;
  &lt;gcm xmlns=&quot;google:mobile:data&quot;&gt;
  {
      &quot;from&quot;:&quot;REGID&quot;,
      &quot;message_id&quot;:&quot;m-1366082849205&quot;
      &quot;error&quot;: ERROR_CODE,
      &quot;message_type&quot;:&quot;nack&quot;
  }
  &lt;/gcm&gt;
&lt;/message&gt;
</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 + "&#64;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>&lt;message id=&quot;&quot;&gt;
  &lt;gcm xmlns=&quot;google:mobile:data&quot;&gt;
  {
      &quot;category&quot;:&quot;com.example.yourapp&quot;, // to know which app sent it
      &quot;data&quot;:
      {
          &quot;hello&quot;:&quot;world&quot;,
      },
      &quot;message_id&quot;:&quot;m-123&quot;,
      &quot;from&quot;:&quot;REGID&quot;
  }
  &lt;/gcm&gt;
&lt;/message&gt;</pre>

<p>Here is the format of the ACK expected by CCS from 3rd-party servers in response to the above message:</p>

<pre>&lt;message id=&quot;&quot;&gt;
  &lt;gcm xmlns=&quot;google:mobile:data&quot;&gt;
  {
      &quot;to&quot;:&quot;REGID&quot;,
      &quot;message_id&quot;:&quot;m-123&quot;
      &quot;message_type&quot;:&quot;ack&quot;
  }
  &lt;/gcm&gt;
&lt;/message&gt;</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>