User Tools

Site Tools


fr:dev:moxl:xec

XEC (pour XMPP Event Controller) est un sous module de Moxl. Il permet de gérer intelligemment les requêtes passées au travers de Moxl. XEC se sous divise lui même en deux grande partie, les Actions et les Payloads.

Dans les deux cas les XECPayload et XECHandler sont à développer par l'intégrateur pour lier les évènements de Moxl à ceux de l'application cible.

Action

Une action XEC est un requête faite sur le serveur XMPP. Ici XEC introduit un système permettant à Moxl de se “souvenir” de requêtes passées et ainsi de renvoyer la réponse à l'endroit dans le code où à été posée la question.

namespace Moxl\Xec\Action\Roster;
 
use Moxl\Xec\Action;
use Moxl\Stanza\Roster
 
class AddItem extends Action
{
    private $_to;
 
    public function request() 
    {
        $this->store();
        Roster::add($this->_to);
    }
 
    public function setTo($to)
    {
        $this->_to = $to;
        return $this;
    }
 
    public function handle($stanza) 
    {
        var_dump('Handle item');
    }
 
    public function errorServiceUnavailable() 
    {
        var_dump('Handle the Error !');
    }
}

Cet exemple montre l'action “d'ajouter un contact à la liste de contact”, cette action hérite de XECAction. Pour ajouter un contact on pourra alors l'appeler ainsi :

use Moxl\Xec\Action\Roster\AddItem;
 
$c = new AddItem();
$c->setTo('contact@serveur.com')
  ->request();

Notez que la ligne

$this->store();

est obligatoire pour demander à XEC d'initialiser la requête pour plus tard gérer sa réponse.

Système de requêtes

L'action store() va permettre de sauvegarder l'instance au moment de donné et va la stocker dans un tableau comprenant toutes les demandes en cours, cette instance sera numérotée avec le numéro de la requête XMPP.

Au retour, XECHandler va vérifier si l'id de la stanza existe dans le tableau et va réinstancier la classe en question. Ainsi le développeur ne sera même pas au courant que la requête et la réponse ont eu lieu en deux exécutions (via deux requêtes différentes sur le serveur XMPP). La requête partant dans la méthode request() et revenant dans la méthode handle() de la même instance.

Réponse

Si tout se passe bien la réponse à la requête arrivera dans la méthode handle($stanza), $stanza étant la réponse convertie au format SimpleXML.

Les valeurs des attributs de la classe sont aussi sauvegardés et restitués quand la bonne réponse revient, libre à vous de jouer avec ça si vous souhaitez conserver certaines valeurs entre la requête et la réponse.

Gestion des erreurs

Tout comme pour les bonnes réponses il peut aussi arriver que la requête en question se solde par une erreur du coté XMPP. XEC gère intelligemment ce retour d'erreur et tente d'appeler au sein de la classe appelante la méthode correspondant au nom de l'erreur retournée (convertie au format CamelCase).

Libre à vous de traiter, ou non, certaines de ces erreurs. Elles sont, dans tout les cas, loguées via syslog dans /var/log/user.log. Dans l'exemple ci-dessus nous avons donc la méthode permettant de traiter l'erreur errorServiceUnavailable. Ce système de gestion d'erreur est intéressant, il pourra en effet permettre de notifier intelligemment l'utilisateur d'une mauvaise manipulation directement sur son navigateur (comme le fait Movim actuellement).

Payload

Les payload, sont “l'inverse” des actions, ce sont les Stanza envoyés par le serveur mais non demandés par le client (ici Moxl). Typiquement les messages envoyés par les contacts lors d'une discussion. De la même façon Moxl, au travers de XEC, essaye de comprendre intelligemment de quelle stanza il s'agit.

Le fonctionnement est ici un peu différent. Voici un petit extrait de XECHandler, il s'agit de la partie s'occupant du hashage des stanza de type payload.

require('XECHandler.array.php');
 
$name = $s->getName();
$ns = $s->getNamespaces();
$node = (string)$s->attributes()->node;
 
if(is_array($ns))
    $ns = current($ns);
 
$hash = md5($name.$ns.$node);
 
MoxlLogger::log('XECHandler : Searching a payload for "'.$name . ':' . $ns . ' [' . $node . ']", "'.$hash.'"');

Concrètement ici, XECHandler va générer un hash unique par “type” de payload, pour générer ce hash il va se baser sur 3 choses :

  • name : le “nom” de la stanza
  • ns : le namespace de la stanza
  • node : le nom de l'attribut “node” si il existe (le plus souvent vide mais indispensable pour des payload venant de noeuds pubsub particuliers).

Exemple

L'arrivée d'un post publié par un contact sur son flux microblogging à toujours cette forme

<event xmlns='http://jabber.org/protocol/pubsub#event'>
  <items node='urn:xmpp:microblog:0'>
    <item id='1cb57d9c-1c46-11dd-838c-001143d5d5db' publisher='romeo@montague.lit'>
     <entry xmlns='http://www.w3.org/2005/Atom'>
       <title type='text'>hanging out at the Caf&amp;#233; Napolitano</title>
       <link rel='alternate'
             type='text/html'
             href='http://montague.lit/romeo/posts/1cb57d9c-1c46-11dd-838c-001143d5d5db'/>
       <link rel='alternate'
             href='xmpp:romeo@montague.lit?;node=urn%3Axmpp%3Amicroblog%3A0;item=1cb57d9c-1c46-11dd-838c-001143d5d5db'/>
       <id>tag:montague.lit,2008-05-08:posts-1cb57d9c-1c46-11dd-838c-001143d5d5db</id>
       <published>2008-05-08T18:30:02Z</published>
       <updated>2008-05-08T18:30:02Z</updated>
     </entry>
   </item>
</event>
</items>

Ici nous aurons donc :

XECHandler va donc faire un hash MD5 de $name.$ns.$node puis regarder dans le tableau contenu dans le fichier XECHandler.array.php pour essayer de trouver une correspondance.

Ici le hash MD5 des trois valeurs donne '96c06e02022480352b6c581286b7eefb'.

$hashToClass = array(
    '9b98cd868d07fb7f6d6cb39dad31f10e' => 'Message',
    'e83b2aea042b74b1bec00b7d1bba2405' => 'Presence',
 
    '96c06e02022480352b6c581286b7eefb' => 'Post'
    );

Si il trouve une clef correspondante dans le tableau il tentera d'instancier la classe en question et d'appeler la méthode handle().

namespace Moxl\Xec\Payload;
 
class Post extends Payload
{
    public function handle($stanza) {   
        var_dump('Post received');
    }
}

Ici tout Post de type Microblog tombera donc dans cette classe, libre au développeur de faire ce qu'il souhaite avec la $stanza passée en paramètre.

Recherche en profondeur

La recherche de Handler adéquats ne se fait pas que sur un seul niveau, comme vous avez pus le remarquer dans l'exemple précédent. XECHandler va également rechercher au sein des stanza pour essayer de détecter des sous informations qui pourraient intéresser le développeur et lever des évènements sur celles-ci.

La recherche en profondeur se limite à trois niveaux maximum (correspondant à trois niveaux de XML imbriqués), en partie pour des soucis de performance.

fr/dev/moxl/xec.txt · Last modified: 2014/04/03 11:50 by edhelas