Odelia>Technologiesbeta

Messagerie instantanée avec Google Talk et Grails

| | | | |

Cet article décrit un exemple d'intégration du protocole de messagerie instantanée XMPP/Jabber dans une application Grails : cet exemple consiste à permettre à tout internaute de dialoguer avec un utilisateur précis Jabber, à partir d'une page web mise à jour grâce à la technologie AJAX ; en l'occurrence, cette démonstration étant en ligne sur le site web GrailsWorks, vous pourrez effectivement converser avec l'auteur de cet article via la page ChatBot. De mon côté, si je suis bien connecté et disponible, vos messages me parviendront au travers de Google Talk, dont j'utilise le client.

Le principe

Le principe de cette messagerie instantanée entre une application web et un utilisateur XMPP/Jabber, repose sur l'utilisation d'un second utilisateur XMPP/Jabber réservé à l'application web. Il est donc nécessaire de déclarer deux comptes différents auprès du serveur XMPP.
Dans notre cas d'utilisation, nous disposons de deux utilisateurs XMPP/Jabber se connectant à Google Talk : l'un d'eux représente l'utilisateur principal, c'est-à-dire moi ; l'autre sert simplement d'intermédiaire pour l'application web développée avec Grails.
Notez que l'intérêt d'utiliser Google Talk est que celui-ci est gratuit et supporte le protocole XMPP/Jabber que nous pouvons adresser avec la librairie Java cliente Smack (celle-ci peut-être téléchargée ici).

L'application web Grails, partie serveur

Dans notre exemple, c'est un service Grails qui a la charge de la connexion au service Google Talk. A titre d'exemple, voici le code Groovy permettant de le faire, ainsi que d'envoyer un message à un utilisateur Google Talk :

import org.jivesoftware.smack.*

def config = new ConnectionConfiguration("talk.google.com", 5222, "gmail.com")

def conn = new XMPPConnection(config)
conn.connect()
conn.login("utilisateur_web@gmail.com", "mot_de_passe")

def chat = conn.getChatManager().createChat("utilisateur_principal@gmail.com", null)
chat.sendMessage("Salut tout le monde !")

Pour que ce code puisse fonctionner, il est nécessaire d'avoir ajouter la librairie Smack smack.jar dans votre projet Grails.
L'utilisateur XMPP/Jabber de JID (Jabber ID) utilisateur_web@gmail.com, utilisé par l'application web, s'authentifie tout d'abord auprès du serveur Google Talk, puis créée une conversation avec l'utilisateur principal (mon JID) afin de pouvoir échanger des messages.

Dans le code ci-dessous, le second argument de l'appel à la méthode ChatManager.createChat est null, mais en réalité il faut passer un objet dont le type supporte l'interface org.jivesoftware.smack.MessageListener de la librairie Smack, de manière à intercepter les messages de réponse de l'utilisateur principal ; le service, de classe ChatBotService, garde un historique des messages échangées entre les deux utilisateurs de manière à pouvoir les restituer à la demande dans une page web.

Même si l'article Instant Messaging in Java Made Easy: The Smack API correspond à une version plus ancienne de la librairie Smack, celui-ci offre une bonne introduction à l'utilisation de XMPP/Jabber à partir de code Java, et donc de Groovy !

La page ChatBot de l'application Grails

La page ChatBot est la page .gsp de l'application Grails servant à tchatcher, mais aussi à montrer le « statut » de l'utilisateur principal : est-il connecté et disponible ? Connecté mais occupé ?
Cette information est retournée par le service ChatBotService, dans un objet de type org.jivesoftware.smack.packet.Presence obtenu par un appel à :

conn.roster.getPresence("utilisateur_principal@gmail.com")

Comment la chaîne de caractères précisant le statut de l'utilisateur principal est-elle mise à jour de manière dynamique dans la page web ?
Pour cela, nous avons recours au support d'AJAX de Grails au travers de la librairie JavasScript prototype ; dans l'entête de la page (balise HTML head) il faut utiliser la balise :

<g:javascript library="prototype" />

La librairie prototype dispose de l'objet Ajax.PeriodicalUpdater qui va permettre des appels périodiques à une action du contrôleur ChatBotController (ce contrôleur fait le lien avec le service ChatBotService). Toujours dans l'entête de la page, nous avons le code suivant :

<g:javascript>
  new Ajax.PeriodicalUpdater('presence', '${createLink(action: "presence")}',
  {
    method: 'get',
    frequency: 5,
    onSuccess: fOnSuccess
  });
  …
</g:javascript>

Ce code, qui génère du code JavaScript à l'exécution, permet un appel, toutes les cinq secondes, à l'action presence du contrôleur ChatBotController (qui est le contrôleur en cours d'utilisation) ; cette action a alors la responsabilité de renvoyer le code HTML qui sera injecté dans l'élément HTML de la page web ayant l'id presence.
Vous l'avez compris : l'action presence récupère l'objet Presence discuté plus haut, depuis le service, et s'en sert pour construire la chaîne de caractères indiquant le statut de l'utilisateur principal.

L'historique des messages échangés entre les deux utilisateurs XMPP/Jabber est récupéré et affiché dans la page web avec une technique similaire.

En conclusion

L'introduction du protocole XMPP/Jabber dans une application web Grails offre des perspectives d'interaction intéressantes, et pas seulement du point de vue de l'utilisation d'une messagerie instantanée : grâce à XMPP/Jabber, il est possible de mettre en place tout un système de notification avec des messages XMPP personnalisés ; cela peut également se réaliser par l'utilisation du service Pub-Sub (extension Publication-Souscription du protocole de base XMPP) que proposent certains serveurs XMPP comme OpenFire.
Dans le cadre d'une application d'entreprise dans lequel on souhaite déployer son propre serveur XMPP, l'exemple présenté dans cet article peut aussi s'appliquer !

balises dans Langages et systèmes

AJAX cajo Camel DSL Grails Groovy Java JBI prefuse RSS ServiceMix SOA