MOD french -> english (2)
[euphorik.git] / js / communication.js
index 985aeed..7288810 100644 (file)
@@ -108,9 +108,114 @@ euphorik.Communication.prototype.requete = function(action, json, funOk, funErro
    \r
    jQuery.ajax(paramsAjax);\r
 };\r
+
+euphorik.Communication.prototype.createCometConnection = function(name) {
+   return new Comet(name, this.getBase);
+};
 \r
 euphorik.Communication.prototype.getBase = function(action) {\r
    return {\r
       "header" : { "action" : action, "version" : euphorik.conf.versionProtocole }\r
    };\r
+};
+
+/**
+  * Permet de gérer les événements (push serveur).
+  * Principe de fonctionnement :
+  *  - La page courante créer un objet euphorik.Comet en indiquant le nom de la page et la version du protocole.
+  *  - La page courante attend un événement en appelant 'waitEvent' (non-bloquant) et en donnant deux fonctions :
+  *    - 'funSend' une fonction qui renvoie l'objet à envoyer avant l'attente, par exemple {"dernierMess" : 23}
+  *       ("header" et "page" sont automatiquement ajoutés à l'objet)
+  *    - 'funsReceive' un ensemble de fonctions à appeler en fonction du "reply" du serveur, par exemple {"set_nom" : function(data) { print("ok : " + data.nom); } }
+  *
+  * l'information envoyée est sous la forme :
+  *  {
+  *     "header" : {"action" : "wait_event", "version" : <v> },
+  *     "page" : <page>
+  *     [..]
+  *  }
+  * l'information reçue est sous la forme :
+  *  {
+  *     "reply" : <reply>
+  *     [..]
+  *  }
+  * <reply> et <page> sont de type chaine
+  *
+  * @page [string] la page courante pour laquelle on écoute des événements (un string)
+  * @util [int] la version
+  */
+Comet = function(page, getBase) {
+   this.page = page;
+   this.getBase = getBase;
+   
+   // l'objet JSONHttpRequest représentant la connexion d'attente
+   this.attenteCourante = undefined;
+   
+   // le multhreading du pauvre, merci javascript de m'offrire autant de primitives pour la gestion de la concurrence...
+   this.stop = false;
+};
+
+/**
+  * Arrête l'attente courante s'il y en a une.
+  */
+Comet.prototype.stopAttenteCourante = function() {
+   this.stop = true;
+         
+   if (this.attenteCourante) {
+      this.attenteCourante.abort();
+   }
+};
+
+/**
+  * Attend un événement lié à la page. Non-bloquant. 
+  * @funSend une fonction renvoyant les données json à envoyer
+  * @funsReceive est un objet comprenant les fonctions à appeler en fonction du "reply"
+  * les fonctions acceptent un paramètre correspondant au données reçues.
+  * exemple : {"new_message" : function(data){ ... }}
+  */
+Comet.prototype.waitEvent = function(funSend, funsReceive) {
+   this.stopAttenteCourante();   
+   this.stop = false;   
+   var thisComet = this;
+      
+   // on doit conserver l'ordre des valeurs de l'objet JSON (le serveur les veut dans l'ordre définit dans le protocole)
+   // TODO : ya pas mieux ?
+   var dataToSend = this.getBase("wait_event")
+   dataToSend["page"] = this.page;
+   
+   var poulpe = funSend();
+   objectEach(poulpe, function(k, v) {
+      dataToSend[k] = v;
+   });
+   
+   this.attenteCourante = jQuery.ajax({
+      type: "POST",
+      url: "request",
+      dataType: "json",
+      // TODO : doit disparaitre
+      timeout: 180000, // timeout de 3min. Gros HACK pas beau. FIXME problème décrit ici : http://groups.google.com/group/jquery-en/browse_thread/thread/8724e64af3333a76
+      data: { action : JSON.stringify(dataToSend) },
+      success:
+         function(data) {
+            funsReceive[data.reply](data);
+         
+            // rappel de la fonction dans 100 ms
+            setTimeout(function(){ thisComet.waitEvent2(funSend, funsReceive); }, 100);
+         },
+      error:
+         function(XMLHttpRequest, textStatus, errorThrown) {
+            ;; console.log("Connexion perdue dans Comet.prototype.waitEvent() : \n" + textStatus);
+            setTimeout(function(){ thisComet.waitEvent2(funSend, funsReceive); }, 1000);
+         }
+   });
+};
+
+/**
+  * Si un stopAttenteCourante survient un peu n'importe quand il faut imédiatement arreter de boucler.
+  */
+Comet.prototype.waitEvent2 = function(funSend, funsReceive) {
+   if (this.stop) {
+      return;
+   }
+   this.waitEvent(funSend, funsReceive);
 };
\ No newline at end of file