X-Git-Url: http://git.euphorik.ch/?p=euphorik.git;a=blobdiff_plain;f=js%2Fcommunication.js;h=72888104f0bc26f7261541fb8384c54073be0285;hp=985aeedce59bc4862a09392b5173a38f9855b495;hb=d6dcd0fd8af56bd4791aa4e621c2e5058033c37a;hpb=27c4a5ac9000ca933f28abfedbf9607f73619615 diff --git a/js/communication.js b/js/communication.js index 985aeed..7288810 100644 --- a/js/communication.js +++ b/js/communication.js @@ -108,9 +108,114 @@ euphorik.Communication.prototype.requete = function(action, json, funOk, funErro jQuery.ajax(paramsAjax); }; + +euphorik.Communication.prototype.createCometConnection = function(name) { + return new Comet(name, this.getBase); +}; euphorik.Communication.prototype.getBase = function(action) { return { "header" : { "action" : action, "version" : euphorik.conf.versionProtocole } }; +}; + +/** + * 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" : }, + * "page" : + * [..] + * } + * l'information reçue est sous la forme : + * { + * "reply" : + * [..] + * } + * et 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