IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

AJAX Discussion :

[AJAX] ajax: doublons sur tchat en developpement


Sujet :

AJAX

  1. #1
    Membre à l'essai
    Homme Profil pro
    Inscrit en
    Septembre 2011
    Messages
    21
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val de Marne (Île de France)

    Informations forums :
    Inscription : Septembre 2011
    Messages : 21
    Points : 19
    Points
    19
    Par défaut [AJAX] ajax: doublons sur tchat en developpement
    Bonjour,

    Je consulte ce forum depuis un petit moment déjà, ce qui m'a souvent été d'une aide précieuse.

    Je développe en ce moment, à titre d'apprentissage, un chat en ajax/PHP/MySQL.

    Jusque là, tout est ok, à part un petit détail: Il arrive parfois que les messages arrivent en doublon.

    Voici un extrait du code jquery:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
     
    var lastMsgId=-1; // à l'arrivée sur le tchat, ajax renvoi cet id message pour récupérer un éventuel historique des messages
    var chatURL="monfichier.php"; // ce fichier renvoie un tableau json_encodé de la forme:
      // data[clear]  drapeau pour id début de lecture BDD dépendant de table SQL vide ou non
      // data[messages]  tableau relatif au(x) nouveau(x) message(s) obetnu(s)
      // data[messages][pseudo]  pseudo expéditeur
      // data[messages][id]  id du message dans la table SQL
      // data[messages][message] message envoyé
      // data[messages][time] date_heure du message
     
     
     
    function getNewMsg()
    { $.ajax(
      { url 	: chatURL, // variable définie en tête de script sur php renvoyant le(s) dernier(s) message(s) en JSON
        type 	: 'POST',
        data	: $.param( { mode : 'getMsg', id	: lastMsgId	} ),
        dataType : 'json',
        error : function(xhr , textStatus, errorThrown)
        { alert('erreur');
          displayError(textStatus); // pas de problème
        },
        success : function(retour)
        { if(retour.errno!=null) displayPHPError(retour); //pas de problème
          else readMsg(retour); // fonction d'affichage de la réponse
          getmsg_interval=setTimeout("getNewMsg();",updInterval);
        }
      });
    }
    // envoi d'un message
    function sendMsg()
    { var msg='';
       var pseudo=$.trim($('#pseudo').val()); // champs caché 
       var msg=$.trim($('#msgBox').val()); // champs de saisie de message
       $('#msgBox').val("");
       $('#msgBox').focus();
      var params={
        mode 	:"sendMsg",
        id		:lastMsgId,
        pseudo	: pseudo,
        message	: msg
      }
      if(msg!='')
      { $.ajax( 
        { url: chatURL,
          type: "POST",
          data: $.param(params),
          dataType: 'json',
          error : function(xhr , textStatus, errorThrown) 
          { displayError(errorThrown);},
          success: function(retour, textStatus)
          { if(retour.errno!=null) displayPHPError(retour);
    	else readMsg(retour);
     
    	//getmsg_interval=setTimeout("getNewMsg();",updInterval); // avec ou sans, le problème est le même
          }
        })
      }
    }
     
    function readMsg(data)
    { clearChat=data.clear; // drapeau pour réinit id de dernier message
      if(clearChat) // si init demandée
      { $("#scroll")[0].innerHTML=""; // vidage du div "#Scrollmsg"
        lastMsgId=-1; //réinit du drapeau
      }
      if(data.messages.length>0) // si nouveau messages
      { if(lastMsgId > data.messages[0].id) return; 
        lastMsgId=data.messages[data.messages.length-1].id; // l'id = id du dernier message arrivé
      }
      $.each(data.messages,function(i,message)
      { var str='';
      str+='<div>'+message.time+'['+message.pseudo+']: '+message.message+'</div>';
      })
      divCible=$('#scroll'); // zone d'affichage du message
      var isScrolledDown=( divCible[0].scrollHeight - divCible[0].scrollTop<= divCible[0].offsetHeight); // calcul pour hauteur de div/messages
      divCible[0].innerHTML+=str;
      divCible[0].scrollTop= isScrolledDown ? divCible[0].scrollHeight : divCible.scrollTop; // forçage descente scrollbar
    }
    les aller-retours client-serveur se passent très bien. c'est à l'affichage que j'ai un doublon de façon aléatoire.
    A noter que le problème ne vient pas de l'insertion du message en BDD, j'ai bien vérifié. Même la réponse de la requête ajax n'indique pas de doublon(merci firebug).

    Il va de soi que j'ai désespérément cherché la panne tout seul. Tantôt j'essayais en stoppant le setTimeout à l'envoi de message, tantôt je vérifiais l'id du dernier message de réponse, je magouillais, transposais, interpolais...

    Si qqn pouvait me donner une piste sur l'erreur à corriger, j'en lui en serais fort reconnaissant.

    Et si par la même occasion on pouvait me donner des exemples CONCRETS sur l'option "ifModified" de $.ajax(), ça serait pas mal non plus. Le web fourmille d'exemples bâclés qui ne font pas avancer le schmilblik pour autant.

    D'avance merci pour les réponses (autres que "télécharge un tchat tout fait", c'est facile, rapide mais ludiquement c'est ZERO, ou bien "consulte la doc jquery", je l'ai déjà fait, pensez donc) et merci aussi pour ce forum où je trouve plus de réponses que n'importe quel autre forum ou tuto.

  2. #2
    Membre à l'essai
    Homme Profil pro
    Inscrit en
    Septembre 2011
    Messages
    21
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val de Marne (Île de France)

    Informations forums :
    Inscription : Septembre 2011
    Messages : 21
    Points : 19
    Points
    19
    Par défaut réponse à moi-même
    Ah ça date!!

    En fait, à l'époque, l'envoi d'un message demandait aussi la récupération des autres messages indépendamment de l’intervalle normal de récupération des messages. Pour peu que l'envoi d'un message et la récupération normale des messages se fassent en même temps, deux requêtes de récupération arrivent AVANT que l'id du message courant ne change coté client.

    Enfin bref, c'était le bordel. J'avais trouvé une solution qui consistait simplement à interrompre le "setInterval" de js lors de l'envoi d'un message. J'aurais aussi pu simplement ne pas récupérer les messages lors d'un envoi...

    Depuis, j'ai révisé ma copie. Un tel système en ajax est tout juste bon pour une messagerie instantanée avec deux ou trois personnes.
    Pour un tchat digne de ce nom, il vaut mieux utiliser les sockets et éventuellement REDIS pour un historique de messages éphémère.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [AJAX] Ajax fonctionnel sauf sur Wordpress
    Par Msieurduss dans le forum AJAX
    Réponses: 3
    Dernier message: 14/02/2011, 01h03
  2. [AJAX] Ajax et onclick sur un href
    Par Interface dans le forum AJAX
    Réponses: 30
    Dernier message: 22/09/2009, 00h08
  3. [AJAX] Ajax/Php fixe sur la meme page
    Par speed034 dans le forum AJAX
    Réponses: 10
    Dernier message: 06/07/2009, 01h04
  4. [AJAX] Récupérer paramètre sur POST dans une servlet
    Par _beber85 dans le forum Servlets/JSP
    Réponses: 1
    Dernier message: 05/04/2006, 11h52
  5. [AJAX] Ajax en mode synchrone sur Safari
    Par The Blec dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 17/02/2006, 17h52

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo