Yop,
Je ne connais pas les technos en question, mais je sais qu'il en existe de plus adaptées que qu'un GET AJAX toutes les secondes.
Perso, n'ayant pas voulu mettre en place de websocket/node ou autre event-driven lorsque j'ai eu besoin d'un petit chat en "temps réel", j'ai utilisé une astuce un peu plus légère: une requête HEAD en AJAX pour savoir si de nouveaux messages sont arrivées et une requête GET lancée uniquement si des messages sont effectivement arrivés. Un petit système de cache coté serveur pour ne pas consulter la BDD lors de la réception du premier AJAX/HEAD, et on arrive à quelque chose de relativement robuste capable de tenir un chat temps réel entre une bonne dizaine de personnes (testé et éprouvé avec des américains, anglais, allemands et français sur le chat).
Pour régler le soucis de scroll, je dirai qu'il faut ramener l’ascenseur en bas que si celui-ci était en bas avant l'actualisation:
L'autre solution, plus élégante mais plus longue à mettre en place, serait de ne pas écraser le contenu du chat, mais bien d'ajouter uniquement les nouveaux messages:
Mais cela requiert un peu plus de code, puisqu'il faut:
• Demander au serveur de renvoyer la liste des nouveaux messages depuis une date donnée
• Récupérer cette réponse et construire les éléments du DOM correspondant à ces nouveaux messages (réponse en JSON conseillée)
• On peut aussi éviter la variable globale (c'est préférable) par "encapsulation"
Dans ce second code, le comportement du navigateur dictera le comportement de la barre de scroll (donc, ce ne sera pas un "comportement forcé par le site"). A tester donc, pour voir le comportement final pour l'utilisateur.
Attention aussi car le setTimeout() me semble mal placé.
Ici, on crée l'objet XHR, puis on lance la requête (AJAX: Asynchronous), et sans en attendre la réponse, on lance le setTimeout().
Résultat: si la réponse met plus de 1 seconde pour arriver, le setTimeout se lancera avant que cette réponse ne soit traitée: il lancera une nouvelle requête AJAX.
On risque donc l'engorgement du client.
Une bonne façon de tester la chose est de mettre un "sleep" (de durée aléatoire) pour allonger la durée de la réponse du serveur.
Solution possible:
placer le setTimeout dans la fonction "onreadystatechange" pour ne le lancer qu'une fois la requête reçue et traitée (avec succès ou erreur).
Je ne connais pas les technos en question, mais je sais qu'il en existe de plus adaptées que qu'un GET AJAX toutes les secondes.
Perso, n'ayant pas voulu mettre en place de websocket/node ou autre event-driven lorsque j'ai eu besoin d'un petit chat en "temps réel", j'ai utilisé une astuce un peu plus légère: une requête HEAD en AJAX pour savoir si de nouveaux messages sont arrivées et une requête GET lancée uniquement si des messages sont effectivement arrivés. Un petit système de cache coté serveur pour ne pas consulter la BDD lors de la réception du premier AJAX/HEAD, et on arrive à quelque chose de relativement robuste capable de tenir un chat temps réel entre une bonne dizaine de personnes (testé et éprouvé avec des américains, anglais, allemands et français sur le chat).
Pour régler le soucis de scroll, je dirai qu'il faut ramener l’ascenseur en bas que si celui-ci était en bas avant l'actualisation:
function refresh()
{
// note: je ne suis pas certain de cette ligne
var scrollEnBas = (element.scrollTop == element.scrollHeight); // l'ascenseur est-il déjà en bas?
...
element = document.getElementById('messages_chatbox');
if (scrollEnBas)
element.scrollTop = element.scrollHeight;
...
}
L'autre solution, plus élégante mais plus longue à mettre en place, serait de ne pas écraser le contenu du chat, mais bien d'ajouter uniquement les nouveaux messages:
var lastTimestamp = new Date().getTime(); // Date du chat actuellement affiché
function refresh()
{
var xhr_object = null;
if(window.XMLHttpRequest)
xhr_object = new XMLHttpRequest();
else if(window.ActiveXObject)
xhr_object = new ActiveXObject('Microsoft.XMLHTTP');
// Note: ici, xhr_object peut valoir "null": il manque un "else { alert('pas de XHR'); }"
var method = 'GET';
var filename = 'chatbox/messages?format=json&depuis='+lastTimestamp;
xhr_object.open(method, filename, true);
xhr_object.onreadystatechange = function()
{
if(xhr_object.readyState == 4)
{
var tmp = xhr_object.responseText;
var newMessages = ...;
// A construire soi-même
// Conseil: récupérer une réponse JSON et construire les noeuds via JSON.parse()
document.getElementById('messages_chatbox').appendChild(newMessages);
}
}
xhr_object.send(null);
lastTimestamp = new Date().getTime();
setTimeout('refresh()', 1000);
}
Mais cela requiert un peu plus de code, puisqu'il faut:
• Demander au serveur de renvoyer la liste des nouveaux messages depuis une date donnée
• Récupérer cette réponse et construire les éléments du DOM correspondant à ces nouveaux messages (réponse en JSON conseillée)
• On peut aussi éviter la variable globale (c'est préférable) par "encapsulation"
Dans ce second code, le comportement du navigateur dictera le comportement de la barre de scroll (donc, ce ne sera pas un "comportement forcé par le site"). A tester donc, pour voir le comportement final pour l'utilisateur.
Attention aussi car le setTimeout() me semble mal placé.
Ici, on crée l'objet XHR, puis on lance la requête (AJAX: Asynchronous), et sans en attendre la réponse, on lance le setTimeout().
Résultat: si la réponse met plus de 1 seconde pour arriver, le setTimeout se lancera avant que cette réponse ne soit traitée: il lancera une nouvelle requête AJAX.
On risque donc l'engorgement du client.
Une bonne façon de tester la chose est de mettre un "sleep" (de durée aléatoire) pour allonger la durée de la réponse du serveur.
Solution possible:
placer le setTimeout dans la fonction "onreadystatechange" pour ne le lancer qu'une fois la requête reçue et traitée (avec succès ou erreur).