441 lines
20 KiB
Plaintext
441 lines
20 KiB
Plaintext
page.title=Implementing GCM Server
|
|
@jd:body
|
|
|
|
<div id="qv-wrapper">
|
|
<div id="qv">
|
|
|
|
<h2>In this document</h2>
|
|
|
|
<ol class="toc">
|
|
<li><a href="#role">Role of the 3rd-party Application Server</a></li>
|
|
<li><a href="#choose">Choosing a GCM Connection Server</a></li>
|
|
<li><a href="#send-msg">Sending Messages</a>
|
|
<ol class="toc">
|
|
|
|
<li><a href="#target">Target</a></li>
|
|
<li><a href="#payload">Payload</a></li>
|
|
<li><a href="#params">Message parameters</a>
|
|
</ol>
|
|
</li>
|
|
<li><a href="#adv">Messaging Concepts and Best Practices</a>
|
|
|
|
<ol class="toc">
|
|
|
|
<li><a href="#collapsible">Send-to-Sync vs. Messages with Payload</a></li>
|
|
<li><a href="#ttl">Setting an Expiration Date for a Message</a></li>
|
|
<li><a href="#multi-senders">Receiving Messages from Multiple Senders</a>
|
|
<li><a href="#lifetime">Lifetime of a Message</a>
|
|
<li><a href="#throttling">Throttling</a>
|
|
</ol>
|
|
|
|
</li>
|
|
</li>
|
|
|
|
</ol>
|
|
|
|
<h2>See Also</h2>
|
|
|
|
<ol class="toc">
|
|
<li><a href="server-ref.html">Server Reference</a></li>
|
|
<li><a href="gs.html">Getting Started</a></li>
|
|
<li><a href="client.html">Implementing GCM Client</a></li>
|
|
<li><a href="ccs.html">Cloud Connection Server (XMPP)</a></li>
|
|
<li><a href="http.html">HTTP Connection Server</a></li>
|
|
|
|
|
|
</ol>
|
|
|
|
</div>
|
|
</div>
|
|
|
|
|
|
<p>The server side of Google Cloud Messaging (GCM) consists of two components:</p>
|
|
<ul>
|
|
<li>Google-provided <strong>GCM Connection Servers</strong>
|
|
take messages from a <a href="{@docRoot}google/gcm/server.html#role">3rd-party app server</a>
|
|
and send them to a GCM-enabled
|
|
application (the "client app") running on a device. For example,
|
|
Google provides connection servers for <a href="{@docRoot}google/gcm/http.html">
|
|
HTTP</a> and <a href="{@docRoot}google/gcm/ccs.html">XMPP (CCS)</a> (XMPP).</li>
|
|
<li>A <strong>3rd-party application server</strong> that you must implement. This application
|
|
server sends data to a GCM-enabled client app via the chosen GCM connection server.</li>
|
|
</ul>
|
|
</p>
|
|
|
|
<p>A full GCM implementation requires both a client implementation and a server
|
|
implementation. For more
|
|
information about implementing the client side, see <a href="client.html">
|
|
Implementing GCM Client</a>.</p>
|
|
|
|
|
|
<h2 id="role">Role of the 3rd-party Application Server</h2>
|
|
|
|
<p>Before you can write client apps that use the GCM feature, you must
|
|
have an application server that meets the following criteria:</p>
|
|
|
|
<ul>
|
|
<li>Able to communicate with your client.</li>
|
|
<li>Able to fire off properly formatted requests to the GCM server.</li>
|
|
<li>Able to handle requests and resend them as needed, using
|
|
<a href="http://en.wikipedia.org/wiki/Exponential_backoff">exponential back-off.</a></li>
|
|
<li>Able to store the API key and client registration IDs. In HTTP, the API key is
|
|
included in the header of POST requests that send messages. In XMPP, the API key is
|
|
used in the SASL PLAIN authentication request as a password to authenticate the connection.</li>
|
|
<li>Able to generate message IDs to uniquely identify each message it sends. Message IDs
|
|
should be unique per sender ID.</li>
|
|
</ul>
|
|
|
|
<p>Here are the basic steps you follow to implement your 3rd-party app server:</p>
|
|
|
|
<ul>
|
|
<li>Decide which GCM connection server(s) you want to use. Note that if you want to use
|
|
upstream messaging from your client applications, you must use XMPP (CCS). For a more detailed
|
|
discussion of this, see <a href="#choose">
|
|
Choosing a GCM Connection Server</a>.</li>
|
|
<li>Decide how you want to implement your app server. We provide helper libraries and code
|
|
samples to assist you with your 3rd-party app server implementation. For example:
|
|
<ul>
|
|
<li>If you decide to use the HTTP connection server, you can use the
|
|
GCM server helper library and demo app to help in implementing your app server.</li>
|
|
<li>If you decide to use the XMPP connection server, you can use
|
|
the provided Python or Java <a href="http://www.igniterealtime.org/projects/smack/">
|
|
Smack</a> demo apps as a starting point.</li>
|
|
<li>Note that Google AppEngine does not support connections to XMPP (CCS).</li>
|
|
</ul>
|
|
</li>
|
|
</ul>
|
|
</li>
|
|
</ul>
|
|
|
|
|
|
<h2 id="choose">Choosing a GCM Connection Server</h2>
|
|
|
|
<p>Currently GCM provides two connection servers: <a href="{@docRoot}google/gcm/http.html">
|
|
HTTP</a> and <a href="{@docRoot}google/gcm/ccs.html">XMPP (CCS)</a>. You can use them
|
|
separately or in tandem. XMPP (CCS) messaging differs from HTTP messaging in the following ways:</p>
|
|
<ul>
|
|
<li>Upstream/Downstream messages
|
|
<ul>
|
|
<li>HTTP: Downstream only, cloud-to-device up to 4KB of data. </li>
|
|
<li>XMPP (CCS): Upstream and downstream (device-to-cloud, cloud-to-device),
|
|
up to 4 KB of data. </li>
|
|
</ul>
|
|
</li>
|
|
<li>Messaging (synchronous or asynchronous)
|
|
<ul>
|
|
<li>HTTP: Synchronous. 3rd-party app servers send messages as HTTP POST requests and
|
|
wait for a response. This mechanism is synchronous and blocks the sender from sending
|
|
another message until the response is received.</li>
|
|
<li>XMPP (CCS): Asynchronous. 3rd-party app servers send/receive messages to/from all their
|
|
devices at full line speed over persistent XMPP connections.
|
|
XMPP (CCS) sends acknowledgment or failure notifications (in the
|
|
form of special ACK and NACK JSON-encoded XMPP messages) asynchronously.</li>
|
|
</ul>
|
|
</li>
|
|
|
|
<li>JSON
|
|
<ul>
|
|
<li>HTTP: JSON messages sent as HTTP POST.</li>
|
|
<li>XMPP (CCS): JSON messages encapsulated in XMPP messages.</li>
|
|
</ul>
|
|
</li>
|
|
<li>Plain Text
|
|
<ul>
|
|
<li>HTTP: Plain Text messages sent as HTTP POST.</li>
|
|
<li>XMPP (CCS): Not supported.</li>
|
|
</ul>
|
|
</li>
|
|
<li>Multicast downstream send to multiple registration IDs.
|
|
<ul>
|
|
<li>HTTP: Supported in JSON message format.</li>
|
|
<li>XMPP (CCS): Not supported.</li>
|
|
</ul>
|
|
</li>
|
|
</ul>
|
|
|
|
|
|
<h2 id="send-msg">Sending Messages</h2>
|
|
|
|
<p>This section gives an overview of sending messages. For details of message syntax,
|
|
see <a href="{@docRoot}google/gcm/server-ref.html">Server Reference</a>.</p>
|
|
|
|
<h3>Overview</h3>
|
|
|
|
<p>Here is the general sequence of events that occurs when a 3rd-party application
|
|
server sends a message (the details vary depending on the platform):</p>
|
|
<ol>
|
|
<li>The 3rd-party app server sends a message to GCM servers.</li>
|
|
<li>The GCM connection server enqueues and stores the message if the device is offline.</li>
|
|
<li>When the device is online, GCM connection server sends the message to the device.</li>
|
|
<li>The client app processes the message. </li>
|
|
</ol>
|
|
|
|
<h3>Implement send request</h3>
|
|
|
|
<p>The following sections describe the basic components involved in
|
|
sending a request. See the <a href="{@docRoot}google/gcm/server-ref.html">Server Reference</a>
|
|
for details.</p>
|
|
|
|
<h4 id="target">Target</h4>
|
|
<p>Required. When your app server sends a message in GCM, it must specify a target.</p>
|
|
<p>For HTTP you must specify the target as one of the following:</p>
|
|
<ul>
|
|
<li><code>registration_ids</code>: For sending to 1 or more devices (up to 1000).
|
|
When you send a message to multiple registration IDs, that is called a multicast message.</li>
|
|
<li><code>notification_key</code>: For sending to multiple devices owned by a single user.</li>
|
|
</ul>
|
|
<p>For CCS (XMPP) you must specify the target as:</p>
|
|
<ul>
|
|
<li>{@code to}: This
|
|
field may contain a single registration ID or a notification key.
|
|
XMPP (CCS) does not support multicast messaging.</li>
|
|
</ul>
|
|
|
|
<h4 id="options">Options</h4>
|
|
|
|
<p>There are various options the 3rd-party app server can set when sending a downstream
|
|
message to a client app. See the <a href="{@docRoot}google/gcm/server-ref.html#table1">
|
|
Server Reference</a> for details. Here are a few examples of possible options:</p>
|
|
|
|
<ul>
|
|
<li>{@code collapse_key}: whether a message should be "send-to-sync" or a "message with
|
|
payload".</li>
|
|
<li>{@code time_to_live}: setting an expiration date for a message.</li>
|
|
<li>{@code dry_run}: Test your server.
|
|
<p>If you want to test your request (either JSON or plain text) without delivering
|
|
the message to the devices, you can set an optional HTTP parameter called
|
|
<code>dry_run</code> with the value <code>true</code>. The result will be almost
|
|
identical to running the request without this parameter, except that the message
|
|
will not be delivered to the devices. Consequently, the response will contain fake
|
|
IDs for the message and multicast parameters.</p>
|
|
</li>
|
|
</ul>
|
|
|
|
<h4 id="payload">Payload</h4>
|
|
<p>Optional. If you are including a payload in the message, you use the <code>data</code>
|
|
parameter to include the payload. This applies for both HTTP and XMPP.</p>
|
|
|
|
<p>See the <a href="{@docRoot}google/gcm/server-ref.html">Server Reference</a> for details on sending
|
|
and receiving messages.</p>
|
|
|
|
<h2 id="adv">Messaging Concepts and Best Practices</h2>
|
|
|
|
<p>This section has a discussion of general messaging topics.</p>
|
|
|
|
<h3 id="collapsible">Send-to-Sync vs. Messages with Payload</h3>
|
|
|
|
<p>Every message sent in GCM has the following characteristics:</p>
|
|
<ul>
|
|
<li>It has a payload limit of 4096 bytes.</li>
|
|
<li>By default, it is stored by GCM for 4 weeks.</li>
|
|
</ul>
|
|
|
|
<p>But despite these similarities, messages can behave very differently depending
|
|
on their particular settings. One major distinction between messages is whether
|
|
they are collapsed (where each new message replaces the preceding message) or not
|
|
collapsed (where each individual message is delivered). Every message sent in GCM
|
|
is either a "send-to-sync" (collapsible) message or a "message with
|
|
payload" (non-collapsible message).</p>
|
|
|
|
<h4 id="s2s">Send-to-sync messages</h4>
|
|
|
|
<p>A send-to-sync (collapsible) message is often a "tickle" that tells
|
|
a mobile application to sync data from the server. For example, suppose you have
|
|
an email application. When a user receives new email on the server, the server
|
|
pings the mobile application with a "New mail" message. This tells the
|
|
application to sync to the server to pick up the new email. The server might send
|
|
this message multiple times as new mail continues to accumulate, before the application
|
|
has had a chance to sync. But if the user has received 25 new emails, there's no
|
|
need to preserve every "New mail" message. One is sufficient. Another
|
|
example would be a sports application that updates users with the latest score.
|
|
Only the most recent message is relevant. </p>
|
|
|
|
<p>GCM allows a maximum of 4 different collapse keys to be used by the GCM server
|
|
at any given time. In other words, the GCM server can simultaneously store 4
|
|
different send-to-sync messages per device, each with a different collapse key.
|
|
For example, Device A can have A1, A2, A3, and A4. Device B can have B1, B2, B3,
|
|
and B4, and so on. If you exceed this number GCM will only keep 4 collapse keys, with no
|
|
guarantees about which ones they will be.</p>
|
|
|
|
<h3 id="payload">Messages with payload</h3>
|
|
|
|
<p>Unlike a send-to-sync message, every "message with payload"
|
|
(non-collapsible message) is delivered. The payload the message contains can be
|
|
up to 4kb. For example, here is a JSON-formatted message in an IM application in
|
|
which spectators are discussing a sporting event:</p>
|
|
|
|
<pre class="prettyprint pretty-json">{
|
|
"registration_id" : "APA91bHun4MxP5egoKMwt2KZFBaFUH-1RYqx...",
|
|
"data" : {
|
|
"Nick" : "Mario",
|
|
"Text" : "great match!",
|
|
"Room" : "PortugalVSDenmark",
|
|
},
|
|
}</pre>
|
|
|
|
<p>A "message with payload" is not simply a "ping" to the
|
|
mobile application to contact the server to fetch data. In the aforementioned IM
|
|
application, for example, you would want to deliver every message, because every
|
|
message has different content. To specify a non-collapsible message, you simply
|
|
omit the <code>collapse_key</code> parameter. Thus GCM will send each message
|
|
individually. Note that the order of delivery is not guaranteed.</p>
|
|
|
|
<p>GCM will store up to 100 non-collapsible messages. After that, all messages
|
|
are discarded from GCM, and a new message is created that tells the client how
|
|
far behind it is.</p>
|
|
|
|
<p>The application should respond by syncing with the server to recover the
|
|
discarded messages. </p>
|
|
|
|
<h4 id="which">Which should I use?</h4>
|
|
<p>If your application does not need to use non-collapsible messages, collapsible
|
|
messages are a better choice from a performance standpoint. However, if you use
|
|
collapsible messages, remember that <strong>GCM only allows a maximum of 4 different collapse
|
|
keys to be used by the GCM server per registration ID at any given time</strong>. You must
|
|
not exceed this number, or it could cause unpredictable consequences.</p>
|
|
|
|
<h3 id="ttl">Setting an Expiration Date for a Message</h3>
|
|
<p>You can use the <code>time_to_live</code> parameter in the send request
|
|
to specify the maximum lifespan of a message.
|
|
The value of this parameter must be a duration from 0 to 2,419,200 seconds, and
|
|
it corresponds to the maximum period of time for which GCM will store and try to
|
|
deliver the message. Requests that don't contain this field default to the maximum
|
|
period of 4 weeks.</p>
|
|
<p>Here are some possible uses for this feature:</p>
|
|
<ul>
|
|
<li>Video chat incoming calls</li>
|
|
<li>Expiring invitation events</li>
|
|
<li>Calendar events</li>
|
|
</ul>
|
|
<h4 id="bg">Background </h4>
|
|
<p>GCM usually delivers messages immediately after they are sent. However,
|
|
this might not always be possible. For example, if the platform is Android,
|
|
the device could be turned off, offline, or otherwise unavailable.
|
|
Or the sender itself might request
|
|
that messages not be delivered until the device becomes active by using the
|
|
<code>delay_while_idle</code> flag. Finally, GCM might intentionally delay messages
|
|
to prevent an application from consuming excessive resources and negatively
|
|
impacting battery life.</p>
|
|
|
|
<p>When this happens, GCM will store the message and deliver it as soon as it's
|
|
feasible. While this is fine in most cases, there are some applications for which
|
|
a late message might as well never be delivered. For example, if the message is
|
|
an incoming call or video chat notification, it will only be meaningful for a
|
|
small period of time before the call is terminated. Or if the message is an
|
|
invitation to an event, it will be useless if received after the event has ended.</p>
|
|
|
|
<p>Another advantage of specifying the expiration date for a message is that GCM
|
|
will never throttle messages with a <code>time_to_live</code> value of 0 seconds.
|
|
In other words, GCM will guarantee best effort for messages that must be delivered
|
|
"now or never." Keep in mind that a <code>time_to_live</code> value of
|
|
0 means messages that can't be delivered immediately will be discarded. However,
|
|
because such messages are never stored, this provides the best latency for
|
|
sending notifications.</p>
|
|
|
|
<p>Here is an example of a JSON-formatted request that includes TTL:</p>
|
|
<pre class="prettyprint pretty-json">
|
|
{
|
|
"collapse_key" : "demo",
|
|
"delay_while_idle" : true,
|
|
"registration_ids" : ["xyz"],
|
|
"data" : {
|
|
"key1" : "value1",
|
|
"key2" : "value2",
|
|
},
|
|
"time_to_live" : 3
|
|
},
|
|
</pre>
|
|
|
|
|
|
<h3 id="multi-senders">Receiving Messages from Multiple Senders</h3>
|
|
|
|
<p>GCM allows multiple parties to send messages to the same application. For
|
|
example, suppose your application is an articles aggregator with multiple
|
|
contributors, and you want each of them to be able to send a message when they
|
|
publish a new article. This message might contain a URL so that the application
|
|
can download the article. Instead of having to centralize all sending activity in
|
|
one location, GCM gives you the ability to let each of these contributors send
|
|
its own messages.</p>
|
|
|
|
<p>To make this possible, all you need to do is have each sender generate its own
|
|
project number. Then include those IDs in the sender field, separated by commas,
|
|
when requesting a registration. Finally, share the registration ID with your
|
|
partners, and they'll be able to send messages to your application using their
|
|
own authentication keys.</p>
|
|
|
|
<p>Note that there is limit of 100 multiple senders.</p>
|
|
|
|
<h3 id="lifetime">Lifetime of a Message</h3>
|
|
|
|
<p>When a 3rd-party server posts a message to GCM and receives a message ID back,
|
|
it does not mean that the message was already delivered to the device. Rather, it
|
|
means that it was accepted for delivery. What happens to the message after it is
|
|
accepted depends on many factors.</p>
|
|
|
|
<p>In the best-case scenario, if the device is connected to GCM, the screen is on,
|
|
and there are no throttling restrictions (see <a href="#throttling">Throttling</a>),
|
|
the message will be delivered right away.</p>
|
|
|
|
<p>If the device is connected but idle, the message will still be
|
|
delivered right away unless the <code>delay_while_idle</code> flag is set to true.
|
|
Otherwise, it will be stored in the GCM servers until the device is awake. And
|
|
that's where the <code>collapse_key</code> flag plays a role: if there is already
|
|
a message with the same collapse key (and registration ID) stored and waiting for
|
|
delivery, the old message will be discarded and the new message will take its place
|
|
(that is, the old message will be collapsed by the new one). However, if the collapse
|
|
key is not set, both the new and old messages are stored for future delivery.
|
|
Collapsible messages are also called <a href="#s2s">send-to-sync messages</a>.</p>
|
|
|
|
<p class="note"><strong>Note:</strong> There is a limit on how many messages can
|
|
be stored without collapsing. That limit is currently 100. If the limit is reached,
|
|
all stored messages are discarded. Then when the device is back online, it receives
|
|
a special message indicating that the limit was reached. The application can then
|
|
handle the situation properly, typically by requesting a full sync.
|
|
<br><br>
|
|
Likewise, there is a limit on how many <code>collapse_key</code>s you can have for
|
|
a particular device. GCM allows a maximum of 4 different collapse keys to be used
|
|
by the GCM server per device
|
|
any given time. In other words, the GCM server can simultaneously store 4 different
|
|
send-to-sync messages, each with a different collapse key. If you exceed this number
|
|
GCM will only keep 4 collapse keys, with no guarantees about which ones they will be.
|
|
See <a href="#s2s">Send-to-sync messages</a> for more information.
|
|
</p>
|
|
|
|
<p>If the device is not connected to GCM, the message will be stored until a
|
|
connection is established (again respecting the collapse key rules). When a connection
|
|
is established, GCM will deliver all pending messages to the device, regardless of
|
|
the <code>delay_while_idle</code> flag. If the device never gets connected again
|
|
(for instance, if it was factory reset), the message will eventually time out and
|
|
be discarded from GCM storage. The default timeout is 4 weeks, unless the
|
|
<code>time_to_live</code> flag is set.</p>
|
|
|
|
<p>Finally, when GCM attempts to deliver a message to the device and the
|
|
application was uninstalled, GCM will discard that message right away and
|
|
invalidate the registration ID. Future attempts to send a message to that device
|
|
will get a <code>NotRegistered</code> error. See <a href="#unreg">
|
|
How Unregistration Works</a> for more information.</p>
|
|
<p>Although is not possible to track the status of each individual message, the
|
|
Google Cloud Console stats are broken down by messages sent to device, messages
|
|
collapsed, and messages waiting for delivery.</p>
|
|
|
|
<h3 id="throttling">Throttling</h3>
|
|
<p>To prevent abuse (such as sending a flood of messages to a device) and
|
|
to optimize for the overall network efficiency and battery life of
|
|
devices, GCM implements throttling of messages using a token bucket
|
|
scheme. Messages are throttled on a per application and per <a href="#collapsible">collapse
|
|
key</a> basis (including non-collapsible messages). Each application
|
|
collapse key is granted some initial tokens, and new tokens are granted
|
|
periodically therefter. Each token is valid for a single message sent to
|
|
the device. If an application collapse key exhausts its supply of
|
|
available tokens, new messages are buffered in a pending queue until
|
|
new tokens become available at the time of the periodic grant. Thus
|
|
throttling in between periodic grant intervals may add to the latency
|
|
of message delivery for an application collapse key that sends a large
|
|
number of messages within a short period of time. Messages in the pending
|
|
queue of an application collapse key may be delivered before the time
|
|
of the next periodic grant, if they are piggybacked with messages
|
|
belonging to a non-throttled category by GCM for network and battery
|
|
efficiency reasons.</p>
|
|
|
|
|