Google Cloud Messaging : Présentation

Le 26 Juin 2012, le service "Android Cloud to Device Messaging" (C2DM) a été officiellement déprécié par Google laissant sa place à "Google Cloud Messaging" (GCM). Comme son prédécesseur ce service permet à une application tiers d’envoyer des messages à des terminaux connectés Android. Au travers d’une série de deux articles nous découvrirons ensemble les différents aspects de GCM en s’appuyant sur un cas concret. Ce premier article a pour but de vous présenter comment fonctionne GCM, ce qu’il est possible de faire avec et en quoi il pourrait vous être utile.

Les acteurs et leurs interactions

Actuellement, il n’existe pas de solution triviale pour envoyer une information directement d’un serveur vers un appareil mobile. Lorsque l’on met en place GCM, il va agir en tant qu’intermédiaire entre l’ application tiers et les terminaux Android. En d’autres termes, lors de l’envoi d’un message du serveur à destination des terminaux Android, ce dernier passera par les serveurs GCM. Ces serveurs ont pour mission de recevoir les messages d’une application tierce et de les transmettre aux mobiles Android concernés (ceux qui ont installés l’application mobile). Les serveurs GCM ne sont pas de simples passe-plats car, comme nous le verrons par la suite, ils sont capables de gérer des files de messages avec application de délais de rétention spécifiques.   

Lors de l’envoi d’un message le serveur doit obligatoirement préciser les identifiants GCM de tous les appareils mobiles qu’il souhaite notifier. L’identifiant GCM est une chaîne de caractères permettant de reconnaître de manière unique un terminal Android pour une application mobile donnée. Il s’obtient lorsque l’application mobile s’enregistre auprès des serveurs GCM. Une fois l’identifiant récupéré, l’application doit le communiquer au serveur afin que l’envoi de messages puisse fonctionner. La phase d’enregistrement des terminaux mobiles est détaillée un peu plus loin dans cet article.

Activer le service GCM

L’activation du service GCM pour l’ application mobile nécessite la création d’un projet via la console d’API google. Une fois le projet créé, il faut activer le service "Google Cloud Messaging" et générer une clé d’API. Une fois toutes ces opérations effectuées, deux informations doivent être conservées :

  • SenderID : il s’agit juste de l’id de votre projet, que vous trouverez à l’onglet "Overview", dans le champ "Project Number". Cet identifiant sera utilisé par l’application mobile afin de préciser qu’elle souhaite recevoir les messages de votre projet.
  • API key : c’est une clé d’autorisation qui permet d’accéder aux services Google. Elle sera utilisée par le serveur d’application et communiquée à chaque envoi de message. Elle permet à Google de vérifier l’identité de l’expéditeur mais aussi d’appliquer les quotas spécifiques à chaque service. Contrairement à Google Maps Javascript API qui est limité à 25 000 requêtes/jour, GCM ne se voit actuellement appliquer aucun quota d’utilisation.

Le détail de cette procédure est disponible ici.

La phase d’enregistrement

Lorsqu’un terminal Android souhaite recevoir des notifications pour une application donnée, il doit effectuer les étapes suivantes  :

  1. S’enregistrer auprès des serveurs GCM à l’aide de son ApplicationID et du SenderID. Pour rappel, l’ApplicationID correspond au nom du package présent dans le manifest.
  2. Si l’enregistrement auprès des serveurs GCM s’est bien déroulé, on récupère un registrationID que l’on communique au serveur d’application. Sinon on recommence à partir de l’étape 1 en appliquant un back-off exponentiel.
  3. Le serveur d’application stocke le registrationID et lui associe les informations qu’il souhaite (compte d’un utilisateur par exemple).

Lors d’une mise à jour ou un backup/restore de l’application mobile, l’identifiant GCM doit être invalidé afin d’éviter de se retrouver dans un état indéterminé. Cette gestion des invalidations ainsi que le principe de canonical id seront vus plus en détail dans le prochain article.

Le message et son envoi 

Le message est l’unité de base qui va transiter du serveur vers les appareils Android. Il a une taille maximale de 4kb, ce qui restreint grandement l’information qui peut être transmise. Un message peut être envoyé au format JSON ou bien PLAIN TEXT. Pour la suite de l’article, seul le format JSON sera traité.

Les principaux champs d’un message sont les suivants (* = champ obligatoire) :

  • registration_ids * : liste des identifiants GCM des terminaux qui vont recevoir ce message, ce champ doit contenir au moins un identifiant mais pas plus de 1000. 
  • data * : le contenu du message, il s’agit d’un objet JSON dont les champs sont représentés sous forme de clé/valeur. Chaque clé sera transformée en nom d’extra dans l’intent une fois le message reçu par le terminal mobile.
  • time_to_live : tout simplement la durée de vie du message en seconde lorsque le terminal est offline. Par défaut la TTL est de quatre semaines.
  • collapse_key : identifiant permettant de grouper un ensemble de messages (cf. section suivante).
  • delay_while_idle : lorsque ce champs est valorisé à true, le message n’est délivré qu’au moment où le terminal redevient actif.
  • dry_run : permet au développeur de tester le message sans qu’il ne soit réellement envoyé aux terminaux.

Une fois le message créé on peut l’envoyer en effectuant une requête POST sur l’url https://android.googleapis.com/gcm/send en n’oubliant pas de spécifier les champs Authorization et Content-Type dans le header HTTP.

Exemple de message avec TTL de 2 jours et collapse key :

Content-Type:application/json
Authorization:key=YOUR_API_KEY

{
  "registration_ids" : ["registrationId1", "registrationId1", ...],
  "data" : {
    "message" : "Update needed"
  },
  "collapse_key" : "application_update",
  "time_to_live" : "172800"
}

Collapse or not collapse?

Les messages sont divisés en deux grandes catégories :

  • Send-to-sync messages : ce sont des messages que le serveur envoie pour notifier aux terminaux que de nouvelles informations sont disponibles et qu’ils peuvent/doivent se synchroniser pour les récupérer. Si plusieurs de ces messages sont émis, il n’est pas nécessaire que les terminaux les reçoivent tous, finalement seul le dernier importe. C’est pourquoi il est possible de spécifier une collapse_key lors de l’envoi d’un message. Lorsqu’un device est déconnecté les messages ayant la même collapse_key ne s’accumuleront pas et seul le "dernier" sera envoyé. Une petite subtilité réside dans l’utilisation du terme "dernier" car une des règles de GCM est qu’aucune garantie n’est fournie quant à l’ordre de livraison des messages. C’est pourquoi le "dernier" message envoyé au terminal n’est pas forcément le dernier émis par le serveur d’application. Pour finir, seules quatre collapse_key sont autorisées à coexister à un instant t sur les serveurs GCM. Si ce nombre est dépassé aucune garantie n’est donnée quant aux quatre clés conservées.
  • Messages with payload : A l’inverse des "send-to-sync messages", les "messages with payload" contiennent de l’information directement utilisable par l’application mobile. Lorsqu’un device est offline, ces messages sont stockés. Cependant il n’est pas possible de stocker plus de 100 messages. Si cette limite est dépassée, ils sont supprimés de la file et le terminal en sera informé dès son retour sur le réseau par un message spécifique.

Le choix du type de message dépend donc de l’information que l’on souhaite faire transiter.

Le throtteling

C’est un mécanisme permettant d’éviter le flood de messages afin de préserver la batterie des devices mobiles. Le principe est simple, chaque collapse_key se voit attribuer un jeu de tokens initial puis périodiquement de nouveaux tokens sont ajoutés. Lorsqu’un message est envoyé il va consommer un token associé à sa collapse_key (ce mécanisme s’applique aussi aux messages n’ayant pas de collapse_key, i.e. collapse_key vide). Ce token est propre à chaque message. Lorsqu’aucun token n’est disponible, l’envoi du message vers le mobile est temporisé jusqu’à ce qu’un token soit de nouveau disponible. Ce mécanisme peut donc être à l’origine de latence pour les applications nécessitant l’envoi d’un grand nombre de messages sur une courte période.

Conclusion

Google Cloud Messaging offre la possibilité de rendre vos applications plus réactives et ainsi améliorer l’expérience utilisateur. De plus il permet de réduire l’empreinte que laisse votre application sur la batterie du terminal mobile. Au travers de cet article, vous avez pu découvrir en détail le fonctionnement de ce service. Dans le prochain nous verrons ensemble comment mettre en place GCM aussi bien côté serveur que mobile.

4 commentaires

  • Bonjour,

    Je tente d’ajouter cette fonctionnalité de notification à mon application. Je voulais savoir si à partir de la « Google APIs Console » il était possible d’identifier les mobiles enregistré?

    cordialement

  • Non ce n’est pas possible, seul le serveur auprès duquel les devices s’enregistrent peut avoir cette information.

  • Bonjour,
    je veux savoir comment je peux faire la désinscription à partir de serveur ?
    c’est ta dire comment supprimer le registration id à partir de database !!!

    cordialement

Laisser un commentaire