f1598d1852
Bug: 19679070, 19716684, 19680472. Change-Id: I14ba1cf53ea42cd7739793fd9873e40e4a2ee6a0
308 lines
13 KiB
Plaintext
308 lines
13 KiB
Plaintext
page.title=Overview
|
|
@jd:body
|
|
|
|
<div id="qv-wrapper">
|
|
<div id="qv">
|
|
|
|
<h2>In this document</h2>
|
|
|
|
<ol class="toc">
|
|
<li><a href="#key">Key Concepts</a></li>
|
|
<li><a href="#arch">Architectural Overview</a></li>
|
|
<li><a href="#lifecycle">Lifecycle Flow</a></li>
|
|
<li><a href="#reg">Register to enable GCM</a></li>
|
|
</ol>
|
|
|
|
</div>
|
|
</div>
|
|
|
|
<p>Google Cloud Messaging (GCM) is a free service that enables developers
|
|
to send downstream messages (from servers to GCM-enabled client apps), and
|
|
upstream messages (from the GCM-enabled client apps to servers).
|
|
This could be a lightweight message telling the client app
|
|
that there is new data to be fetched from the server (for instance, a "new email"
|
|
notification informing the app that it is out of sync with the back end),
|
|
or it could be a message containing up to 4kb of payload
|
|
data (so apps like instant messaging can consume the message directly). The GCM
|
|
service handles all aspects of queueing of messages and delivery to and from
|
|
the target client app.</p>
|
|
|
|
|
|
<h2 id="key">Key Concepts</h2>
|
|
|
|
<p>This table summarizes the key terms and concepts involved in GCM. It is
|
|
divided into these categories:</p>
|
|
<ul>
|
|
<li><strong>Components</strong> — The entities that play a primary role in
|
|
GCM.</li>
|
|
<li><strong>Credentials</strong> — The IDs and tokens that are used in
|
|
GCM to ensure that all parties have been authenticated, and
|
|
that the message is going to the correct place.</li>
|
|
</ul>
|
|
|
|
<p class="table-caption" id="table1">
|
|
<strong>Table 1.</strong> GCM components and credentials.</p>
|
|
|
|
<table>
|
|
<tr>
|
|
<th colspan="2">Components</th>
|
|
</tr>
|
|
<tr>
|
|
<td><strong>GCM Connection Servers</strong></td>
|
|
<td>The Google-provided servers involved in sending messages between the
|
|
3rd-party app server and the client app.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><strong>Client App</strong></td>
|
|
<td>A GCM-enabled client app that communicates with a 3rd-party app server.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><strong>3rd-party App Server</strong></td>
|
|
<td>An app server that you write as part of implementing
|
|
GCM. The 3rd-party app server sends data to a client app via
|
|
the GCM connection server.</td>
|
|
</tr>
|
|
<tr>
|
|
<th colspan="2">Credentials</th>
|
|
</tr>
|
|
<tr>
|
|
<td id="senderid"><strong>Sender ID</strong></td>
|
|
<td>A project number you acquire from the API console, as described in
|
|
<a href="gs.html#create-proj">Getting Started</a>. The sender
|
|
ID is used in the <a href="#register">registration process</a> to identify a
|
|
3rd-party app server that is permitted to send messages to the client app.</td>
|
|
</tr>
|
|
<tr>
|
|
<td id="apikey"><strong>Sender Auth Token</strong></td>
|
|
<td>An API key that is saved on the 3rd-party app
|
|
server that gives the app server authorized access to Google services.
|
|
The API key is included in the header of POST requests.
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td><strong>Application ID</strong></td>
|
|
<td>The client app that is registering to receive messages. How this is implemented
|
|
is platform-dependent. For example, an Android app
|
|
is identified by the package name from the <a href="client.html#manifest">manifest</a>.
|
|
This ensures that the messages are targeted to the correct Android app.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><strong>Registration ID</strong></td>
|
|
<td>An ID issued by the GCM servers to the client app that allows
|
|
it to receive messages. Note that registration IDs must be kept secret.
|
|
|
|
</td>
|
|
</tr>
|
|
|
|
</table>
|
|
|
|
<h2 id="arch">Architectural Overview</h2>
|
|
|
|
<p>A GCM implementation includes a Google-provided
|
|
connection server, a 3rd-party app server that interacts with the connection
|
|
server, and a GCM-enabled client app. For example, this diagram shows GCM
|
|
communicating with a client app on an Android device:</p>
|
|
|
|
<img src="{@docRoot}images/gcm/GCM-arch.png">
|
|
|
|
<p class="img-caption">
|
|
<strong>Figure 1.</strong> GCM Architecture.
|
|
</p>
|
|
|
|
<p>This is how these components interact:</p>
|
|
<ul>
|
|
<li>Google-provided <strong>GCM Connection Servers</strong> take messages from
|
|
a 3rd-party app server and send these messages to a
|
|
GCM-enabled client app (the "client app").
|
|
Currently Google provides connection servers for <a href="http.html">HTTP</a>
|
|
and <a href="ccs.html">XMPP</a>.</li>
|
|
<li>The <strong>3rd-Party App Server</strong> is a component that you
|
|
implement to work with your chosen GCM connection server(s). App servers send
|
|
messages to a GCM connection server; the connection server enqueues and stores the
|
|
message, and then sends it to the client app.
|
|
For more information, see <a href="server.html">Implementing GCM Server</a>.</li>
|
|
<li>The <strong>Client App</strong> is a GCM-enabled client app.
|
|
To receive GCM messages, this app must register with GCM and get a
|
|
registration ID. If you are using the <a href="ccs.html">XMPP</a> (CCS) connection
|
|
server, the client app can send "upstream" messages back to the 3rd-party app server.
|
|
For more information on how to implement the client app, see
|
|
the documentation for your platform.</li>
|
|
</ul>
|
|
|
|
<h2 id="lifecycle">Lifecycle Flow</h2>
|
|
|
|
<ul>
|
|
<li><strong>Register to enable GCM</strong>. A client app registers to receive messages.
|
|
For more discussion, see <a href="#register">Register to enable GCM</a>.</li>
|
|
<li><strong>Send and receive downstream messages</strong>.
|
|
<ul>
|
|
<li>Send a message. A 3rd-party app server sends messages to the client app:
|
|
<ol>
|
|
<li>The 3rd-party app server <a href="server.html#send-msg">sends a message</a>
|
|
to GCM connection servers.</li>
|
|
<li>The GCM connection server enqueues and stores the message if the device is offline.</li>
|
|
<li>When the device is online, the GCM connection server sends the message to the device. </li>
|
|
<li>On the device, the client app receives the message according to the platform-specific implementation.
|
|
See your platform-specific documentation for details.</li>
|
|
</ol>
|
|
</li>
|
|
<li>Receive a message. A client app
|
|
receives a message from a GCM server. See your platform-specific documentation for details
|
|
on how a client app in that environment processes the messages it receives.</li>
|
|
</ul>
|
|
</li>
|
|
|
|
<li><strong>Send and receive upstream messages</strong>. This feature is only available if
|
|
you're using the <a href="ccs.html">XMPP Cloud Connection Server</a> (CCS).
|
|
<ul>
|
|
<li>Send a message. A client app sends messages to the 3rd-party app server:
|
|
<ol>
|
|
<li>On the device, the client app sends messages to XMPP (CCS).See your platform-specific
|
|
documentation for details on how a client app can send a message to XMPP (CCS).</li>
|
|
<li>XMPP (CCS) enqueues and stores the message if the server is disconnected.</li>
|
|
<li>When the 3rd-party app server is re-connected, XMPP (CCS) sends the message to the 3rd-party app server.</li>
|
|
</ol>
|
|
</li>
|
|
<li>Receive a message. A 3rd-party app server receives a message from XMPP (CCS) and then does the following:
|
|
<ol>
|
|
<li>Parses the message header to verify client app sender information.
|
|
<li>Sends "ack" to GCM XMPP connection server to acknowledge receiving the message.
|
|
<li>Optionally parses the message payload, as defined by the client app.
|
|
</ol>
|
|
</li>
|
|
</ul>
|
|
|
|
</li>
|
|
|
|
|
|
</ul>
|
|
|
|
<h2 id="reg">Register to enable GCM</h2>
|
|
|
|
<p>Regardless of the platform you're developing on, the first step
|
|
a client app must do is register with GCM. This section covers some of the general
|
|
best practices for registration and unregistration. See your platform-specific docs for
|
|
details on writing a GCM-enabled client app on that platform.</p>
|
|
|
|
<h3 id="reg-state">Keeping the Registration State in Sync</h3>
|
|
<p>Whenever the app registers as described in
|
|
<a href="{@docRoot}google/gcm/client.html">Implementing GCM Client</a>,
|
|
it should save the registration ID for future use, pass it to the
|
|
3rd-party server to complete the registration, and keep track of
|
|
whether the server completed the registration. If the server fails
|
|
to complete the registration, the client app should retry passing the
|
|
registration ID to 3rd-party app server to complete the registration.
|
|
If this continues to fail, the client app should unregister from GCM.</p>
|
|
|
|
<p>There are also two other scenarios that require special care:</p>
|
|
<ul>
|
|
<li>Client app update</li>
|
|
<li>Backup and restore
|
|
</li>
|
|
</ul>
|
|
<p><bold>Client app update:</bold> When a client app is updated, it should invalidate its existing registration
|
|
ID, as it is not guaranteed to work with the new version. The recommended way to achieve
|
|
this validation is by storing the current app version when a registration
|
|
ID is stored. Then when the app starts, compare the stored value with
|
|
the current app version. If they do not match, invalidate the stored data
|
|
and start the registration process again.</p>
|
|
|
|
<p><bold>Backup and restore: </bold> You should not save the registration ID when an app is
|
|
backed up. This is because the registration ID could become invalid by the time
|
|
the app is restored, which would put the app in an invalid state
|
|
(that is, the app thinks it is registered, but the server and GCM do not
|
|
store that registration ID anymore—thus the app will not get more
|
|
messages). The best practice is to initiate the registration process as if the app has been
|
|
installed for the first time.</p>
|
|
|
|
<h4 id="canonical">Canonical IDs</h4>
|
|
<p>If a bug in the app triggers multiple
|
|
registrations for the same device, it can be hard to reconcile state and you might
|
|
end up with duplicate messages.</p>
|
|
<p>GCM provides a facility called "canonical registration IDs" to easily
|
|
recover from these situations. A canonical registration ID is defined to be the ID
|
|
of the last registration requested by your app. This is the ID that the
|
|
server should use when sending messages to the device.</p>
|
|
<p>If later on you try to send a message using a different registration ID, GCM
|
|
will process the request as usual, but it will include the canonical registration
|
|
ID in the <code>registration_id</code> field of the response. Make sure to replace
|
|
the registration ID stored in your server with this canonical ID, as eventually
|
|
the ID you're using will stop working.</p>
|
|
|
|
<h3 id="retry">Automatic Retry Using Exponential Back-Off</h3>
|
|
|
|
<p>When registration or unregistration fails, the app should retry the failed operation.</p>
|
|
<p>In the simplest case, if your app attempts to register and GCM is not a
|
|
fundamental part of the app, the app could simply ignore the error
|
|
and try to register again the next time it starts. Otherwise, it should retry the
|
|
previous operation using exponential back-off. In exponential back-off, each time
|
|
there is a failure, it should wait twice the previous amount of time before trying
|
|
again.
|
|
</p>
|
|
|
|
<h3 id="unreg">Unregistration</h3>
|
|
|
|
<p>This section explains when you should unregister in GCM and what happens
|
|
when you do.</p>
|
|
|
|
<h4 id="unreg-why">Why you should rarely unregister</h4>
|
|
|
|
<p>You should only need to unregister in rare cases, such as
|
|
if you want an app to stop receiving messages, or if you suspect that the registration ID has
|
|
been compromised. In general, once an app has a registration ID, you shouldn't need
|
|
to change it.</p>
|
|
|
|
<p>In particular, you should never unregister your app as a mechanism for
|
|
logout or for switching between users, for the following reasons:</p>
|
|
|
|
<ul>
|
|
<li>A registration ID isn't associated with a particular
|
|
logged in user. If you unregister and then re-register, GCM may return the same
|
|
ID or a different ID—there's no guarantee either way.</li>
|
|
|
|
<li>Unregistration may take up to 5 minutes to propagate.</li>
|
|
<li>After unregistration, re-registration may again take up to 5 minutes to
|
|
propagate. During this time messages may be rejected due to the state of being
|
|
unregistered, and after all this, messages may still go to the wrong user.</li>
|
|
</ul>
|
|
|
|
|
|
<p>To make sure that messages go to the intended user:</p>
|
|
|
|
<ul>
|
|
<li>Your app server can maintain a mapping between the current user
|
|
and the registration ID.</li>
|
|
<li>The app can then check to ensure that messages it
|
|
receives match the logged in user.</li>
|
|
</ul>
|
|
|
|
|
|
<h4 id="unreg-how">How unregistration works</h4>
|
|
|
|
<p>A client app can be automatically unregistered after it is uninstalled.
|
|
However, this process does not happen right away. What happens in
|
|
this scenario is as follows:</p>
|
|
<ol>
|
|
<li>The end user uninstalls the client app.</li>
|
|
<li>The 3rd-party app server sends a message to GCM server.</li>
|
|
<li>The GCM server sends the message to the GCM client on the device.</li>
|
|
<li>The GCM client on the device receives the message and detects that the client app has been
|
|
uninstalled; the detection details depend on the platform on which the client app is running.
|
|
</li>
|
|
<li>The GCM client on the device informs the GCM server that the client app was uninstalled.</li>
|
|
<li>The GCM server marks the registration ID for deletion.</li>
|
|
<li>The 3rd-party app server sends a message to GCM.</li>
|
|
<li>The GCM returns a <code>NotRegistered</code> error message to the 3rd-party app server.</li>
|
|
<li>The 3rd-party app server deletes the registration ID.
|
|
</li>
|
|
</ol>
|
|
|
|
<p>Note that it might take a while for the registration ID be completely removed
|
|
from GCM. Thus it is possible that messages sent during step 7 above gets a valid
|
|
message ID as response, even though the message will not be delivered to the client app.
|
|
Eventually, the registration ID will be removed and the server will get a
|
|
<code>NotRegistered</code> error, without any further action being required from
|
|
the 3rd-party server (this scenario happens frequently while an app is
|
|
being developed and tested).</p>
|
|
|