diff options
Diffstat (limited to 'docs/html/google/gcm/adv.jd')
| -rw-r--r-- | docs/html/google/gcm/adv.jd | 410 |
1 files changed, 0 insertions, 410 deletions
diff --git a/docs/html/google/gcm/adv.jd b/docs/html/google/gcm/adv.jd deleted file mode 100644 index 95497e3..0000000 --- a/docs/html/google/gcm/adv.jd +++ /dev/null @@ -1,410 +0,0 @@ -page.title=GCM Advanced Topics -@jd:body - -<div id="qv-wrapper"> -<div id="qv"> - -<h2>Quickview</h2> - -<ul> -<li>Learn more about GCM advanced features.</li> -</ul> - - -<h2>In this document</h2> - -<ol> -<li><a href="#lifetime">Lifetime of a Message</a></li> -<li><a href="#throttling">Throttling</a></li> -<li><a href="#reg-state">Keeping the Registration State in Sync</a> - <ol> - <li><a href="#canonical">Canonical IDs</a></li> - </ol> -</li> -<li><a href="#retry">Automatic Retry Using Exponential Back-Off</a></li> -<li><a href="#unreg">Unregistration</a> - <ol> - <li><a href="#unreg-why">Why you should rarely unregister</a></li> - <li><a href="#unreg-how">How unregistration works</a></li> - </ol> -</li> -<li><a href="#collapsible">Send-to-Sync vs. Messages with Payload</a> - <ol> - <li><a href="#s2s">Send-to-sync messages</a></li> - <li><a href="#payload">Messages with payload</a></li> -<li><a href="#which">Which should I use?</a></li> - </ol> -</li> -<li><a href="#ttl">Setting an Expiration Date for a Message</a> </li> -<li><a href="#throttling"></a><a href="#multi-senders">Receiving Messages from -Multiple Senders</a></li> -</ol> - -</div> -</div> -<p>This document covers advanced topics for GCM.</p> - - - - -<h2 id="msg-lifetime">Lifetime of a Message</h2> -<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> - -<h2 id="throttling">Throttling</h2> -<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> - -<h2 id="reg-state">Keeping the Registration State in Sync</h2> -<p>Whenever the application 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, it should try again or unregister from GCM.</p> - -<p>There are also two other scenarios that require special care:</p> -<ul> - <li>Application update</li> - <li>Backup and restore - </li> -</ul> -<p>When an application is updated, it should invalidate its existing registration -ID, as it is not guaranteed to work with the new version. Because there is no -lifecycle method called when the application is updated, the best way to achieve -this validation is by storing the current application version when a registration -ID is stored. Then when the application is started, compare the stored value with -the current application version. If they do not match, invalidate the stored data -and start the registration process again.</p> - -<p>Similarly, you should not save the registration ID when an application is -backed up. This is because the registration ID could become invalid by the time -the application is restored, which would put the application in an invalid state -(that is, the application thinks it is registered, but the server and GCM do not -store that registration ID anymore—thus the application will not get more -messages).</p> -<h3 id="canonical">Canonical IDs</h3> -<p>On the server side, as long as the application is behaving well, everything -should work normally. However, if a bug in the application 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 application. 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> - -<h2 id="retry">Automatic Retry Using Exponential Back-Off</h2> - -<p>When registration or unregistration fails, the app should retry the failed operation.</p> -<p>In the simplest case, if your application attempts to register and GCM is not a -fundamental part of the application, the application 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. If the register (or unregister) operation was synchronous, it could be retried -in a simple loop. However, since it is asynchronous, the best approach is to schedule -a {@link android.app.PendingIntent} to retry the operation. - -<h2 id="unreg">Unregistration</h2> - -<p>This section explains when you should unregister in GCM and what happens -when you do.</p> - -<h3 id="unreg-why">Why you should rarely unregister</h3> - -<p>A registration ID (regID) represents a particular Android application running -on a particular device. 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 regID has -been compromised. In general, though, once an app has a regID, 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 regID maps an app to a device. It 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>The solution is to manage your own mapping between users, the regID, and -individual messages:</p> - -<ul> - <li>Your app server should maintain a mapping between the current user -and the regID. This should include information about which user is supposed to -receive a particular message.</li> - <li>The app running on the device should check to ensure that messages it -receives match the logged in user.</li> -</ul> - - -<h3 id="unreg-how">How unregistration works</h3> - -<p>An application can be automatically unregistered after it is uninstalled from -the device. However, this process does not happens right away, as Android does not -provide an uninstall callback. What happens in this scenario is as follows:</p> -<ol> - <li>The end user uninstalls the application.</li> - <li>The 3rd-party server sends a message to GCM server.</li> - <li>The GCM server sends the message to the device.</li> - <li>The GCM client receives the message and queries Package Manager about -whether there are broadcast receivers configured to receive it, which returns -<code>false</code>. -</li> - <li>The GCM client informs the GCM server that the application was uninstalled.</li> - <li>The GCM server marks the registration ID for deletion.</li> - <li>The 3rd-party server sends a message to GCM.</li> - <li>The GCM returns a <code>NotRegistered</code> error message to the 3rd-party server.</li> - <li>The 3rd-party deletes the registration ID. - </li> -</ol> - -<p class ="note"><strong>Note:</strong> The GCM client is the Google Cloud -Messaging framework present on the device.</p> - -<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 device. -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 application is -being developed and tested).</p> - -<h2 id="collapsible">Send-to-Sync vs. Messages with Payload</h2> - -<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). These concepts are described in more -detail in the following sections.</p> - -<h3 id="s2s">Send-to-sync messages</h3> - -<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, so it makes sense to have each new -message replace the preceding message. </p> - -<p>The email and sports applications are cases where you would probably use the -GCM <code>collapse_key</code> parameter. A <em>collapse key</em> is an arbitrary -string that is used to collapse a group of like messages when the device is offline, -so that only the most recent message gets sent to the client. For example, -"New mail," "Updates available," and so on</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. The message is delivered through a regular -<code>com.google.android.c2dm.intent.RECEIVE</code> intent with the -extra <code>message_type</code>, for which the value is always the string -"deleted_messages".</p> - -<p>The application should respond by syncing with the server to recover the -discarded messages. </p> - -<h3 id="which">Which should I use?</h3> - <p>If your application does not need to use non-collapsible messages, collapsible -messages are a better choice from a performance standpoint, because they put less -of a burden on the device battery. 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 device at any given time</strong>. You must not exceed this number, or it could cause -unpredictable consequences.</p> - -<h2 dir="ltr" id="ttl">Setting an Expiration Date for a Message</h2> -<p>The Time to Live (TTL) feature lets the sender specify the maximum lifespan -of a message using the <code>time_to_live</code> parameter in the send request. -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> -<h3 id="bg">Background </h3> -<p>GCM will usually deliver messages immediately after they are sent. However, -this might not always be possible. For example, the device could be turned off, -offline, or otherwise unavailable. In other cases, 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> - - -<h2 id="multi-senders">Receiving Messages from Multiple Senders</h2> - -<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>This code snippet illustrates this feature. Senders are passed as an intent -extra in a comma-separated list:</p> - -<pre class="prettyprint pretty-java">Intent intent = new Intent(GCMConstants.INTENT_TO_GCM_REGISTRATION); -intent.setPackage(GSF_PACKAGE); -intent.putExtra(GCMConstants.EXTRA_APPLICATION_PENDING_INTENT, - PendingIntent.getBroadcast(context, 0, new Intent(), 0)); -String senderIds = "968350041068,652183961211"; -intent.putExtra(GCMConstants.EXTRA_SENDER, senderIds); -ontext.startService(intent); - </pre> - -<p>Note that there is limit of 100 multiple senders.</p> |
