Un tchat, mélangeant les techniques suivantes: javascript, AJAX, PHP, mysql et JSON, en moins de 150 lignes. Il y a quelques mois Hempstar proposait sur ce blog sa version du chat. Comme j'ai énormément progressé dans ces langages de programmation, je me demandais si je saurai le faire, en quelques heures, en bouffant moins de ressources réseau.
Réponse: Oui, sans trop lutter; Le voici à l'aide d'une iframe:
Mises à jour fev 2012:
- smileys (désactivables). Ceux que j'ai mis dans le package proviennent de phpBB3 http://www.phpbb.com/ en GNU GPL licence V2 (enfin je crois).
- Les caracteres + et & n'étaient pas pris en charge. c'est résolu.
- la barre de défilement ne descend automatiquement que s'il y a des nouveaux messages.
- la touche e,ntrée envoie le message, pas un retour à la ligne.
Pour l'installer:
Creez la table tchat dans une base de données:
CREATE TABLE `tchat` ( `time` TIMESTAMP NOT NULL , `pseudo` TEXT NOT NULL , `message` TEXT NOT NULL , PRIMARY KEY ( `time` , `pseudo` ( 5 ) ) ) ENGINE = MYISAM
- Télécharger l'archive là:
tchat.tar.gz - Décompressez la dans un dossier sur votre site
- Editez le fichier index.php pour renseigner les paramètres de la base de données
C'est pret!
Quelques explications sur le code:
La base de données
Basique:
CREATE TABLE `tchat` ( `time` TIMESTAMP NOT NULL , `pseudo` TEXT NOT NULL , `message` TEXT NOT NULL , PRIMARY KEY ( `time` , `pseudo` ( 5 ) ) ) ENGINE = MYISAM
le code PHP
Deux fonctions: l'enregistrement d'un nouveau message et l'envoi des informations sur les nouveaux messages dans un tableau au format JSON. Lors du refresh on n'envoie que les messages dont la date est supérieure à celle passée en variable POST $lasttime. L'enregistrement se contente d'une requête et ne retourne rien.
<?php //**********Options à parametrer************** $nombreDeMessagesGardes=50; $enableSmileys=true; $smileysPath="smilies/"; 'username' => '', 'password' => '', 'host' => 'localhost', 'database' => '' ); //********** Fin des options ************ //connexion mysql erreur('Impossible de se connecter à MySQL'); die; } //Nettoyer les variables en entrée foreach($_POST as $keyname =>$value){ } $act=""; } switch($act) { case "refresh": die; } //echo "SELECT time,pseudo,message FROM tchat WHERE time > '".$lasttime."' ORDER BY time ASC LIMIT 0,50"; $rs=mysql_query("SELECT time,pseudo,message FROM tchat WHERE time > '".$lasttime."' ORDER BY time DESC LIMIT 0".$nombreDeMessagesGardes); } die; break; case "add": echo "variable vide"; } //les smilays include $smileysPath."smileys.php"; foreach($phpbb_smilies as $smile){ $message=str_replace($smile['code'],'<img src="'.$smileysPath.$smile['smiley_url'].'" alt="'.$smile['smiley_url'].'"/>',$message); } } die; break; case "": break; default: //aucun des cas prévu, on stoppe le script. die; break; } ?>
Le code javascript
Trois function, la functrion ajax utilisée par les deux autres pour faire des appels au serveur, la function pour ajouter un message et la function pour raffraichir le tchat. Cette dernière est bouclée : t=setTimeout("refreshchat(lasttime)",3000); permet de la rappeler 3 secondes plus tard (délai qui me semble un bon compromis entre la charge réseau et la fluidité).
L'array contenant les derniers messages du tchat est récupéré de cette manière:
eval ("messages = " + xhr.responseText);
Et pour les ajouter à la fin, J'utilise le DOM avec la function appendChild:
var pmessage=document.createElement("p"); pmessage.innerHTML='<em class="date">'+ messages[l][0] + '</em><em class="pseudo">' + messages[l][1] + ':</em>' + messages[l][2]; document.getElementById("tchat").appendChild(pmessage);
function onKeyEnter(key) { if (key == 13) { sendmessage(document.getElementById('pseudo').value,document.getElementById('message').value); return true; } return false; } function Ajx() { var request = false; try {request = new ActiveXObject('Msxml2.XMLHTTP');} catch (err2) {try {request = new ActiveXObject('Microsoft.XMLHTTP');} catch (err3) {try {request = new XMLHttpRequest();} catch (err1) {request = false;} } } return request; } function refreshchat(time) { var xhr = Ajx(); xhr.onreadystatechange = function(){if(xhr.readyState == 4){ if(xhr.status == 200) { var messages= new Array(); eval ("messages = " + xhr.responseText); var yaDesNouveauxMessages=false; for (var l in messages){ yaDesNouveauxMessages=true; var pmessage=document.createElement("p"); pmessage.innerHTML='<em class="date">'+ messages[l][0] + '</em><em class="pseudo">' + messages[l][1] + ':</em>' + messages[l][2]; document.getElementById("tchat").appendChild(pmessage); lasttime=messages[l][0]; } if (yaDesNouveauxMessages){ //on redescend la scrollbar document.getElementById("tchat").scrollTop=document.getElementById("tchat").scrollHeight; } t=setTimeout("refreshchat(lasttime)",3000); }else{ alert("Error code " + xhr.status); } }}; xhr.open("POST", "index.php", true); xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); xhr.send('act=refresh&lasttime=' + time); } function sendmessage(pseudo,message) { pseudo = pseudo.replace(/&/g,"%26"); message= message.replace(/&/g,"%26"); pseudo = pseudo.replace(/\+/g,"%2B"); message= message.replace(/\+/g,"%2B"); if ((message=='') || (pseudo=='')){ alert('Veuillez mettre un pseudo et un message'); } var xhr = Ajx(); xhr.onreadystatechange = function(){if(xhr.readyState == 4){ if(xhr.status == 200) { document.getElementById("message").value=""; }else{ alert("Error code " + xhr.status); } }}; xhr.open("POST", "index.php", true); xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); xhr.send('act=add&pseudo=' + pseudo + '&message=' + message ); }
Le Body HTML:
<body>
<div id="page">
<div id="tchat">
<script type="text/javascript">
<!--
lasttime='0';
refreshchat(lasttime);
//-->
</script>
</div>
<div id="reponse">
<fieldset><legend>Envoyer un message</legend>
<label for="pseudo">Pseudonyme:</label><input type="text" id="pseudo"/>
<label for="message">Message</label><textarea onkeypress="onKeyEnter(event.keyCode);" id="message"></textarea>
<input type="button" value="Envoyer" onClick="sendmessage(document.getElementById('pseudo').value,document.getElementById('message').value);"/>
</fieldset>
</div>
</div>
</body>
C'est super sommaire comme tchat.
Il vous faudra probablement coder certains certains compléments, comme l'authentification des utilisateurs, faire des salons différents etc... L'objectif ici était juste de montrer que c'est pas tres dur, pas de fournir un produit fini, mais plutot un struc simple et facilement intégrable sur un blog, site ou extranet...
Je m'envoie quelques fleurs:
Au niveau de la charge serveur, il n'y a pas de session ouverte (mémoire économisée), Le retour d'information est relativement optimisé grâce au JSON. Idéalement on pourrait mettre en cache la valeur du dernier timestamp pour n'ouvrir une connexion mysql que s'il y a des messages au timestamp supérieur à celui envoyé par la navigateur (et donc dans la majorité des cas ne même pas ouvrir de connexion mysql).

AJAX
Voici une fonction pour envoyer un e-mail en PHP avec des pièces jointes quelque soit leur extension (ou presque).

J'ai remarqué que les spammeurs qui sévissent sur mon blog, ont souvent ces deux points communs:
Derniers commentaires