Jednoduchý chat s pomocí AJAXu
Po dvou teoretických úvodech (Využití technologie AJAX a AJAX podruhé)si dnes předvedeme AJAX v praxi. Bude to jednoduchý chat. Jednoduchý ale názorný
. Při jeho tvorbě využijeme AJAX+PHP+MySQL.
Nejprve se zamyslíme co od něj očekáváme:

Nyní k serverovým skriptům. Požadujeme 2 operace - výběr příspěvků a zápis. Zápis je jednoduchý jedná se pouze o vložení záznamu do databáze. Výpis příspěvků již bude o malinko složitější. Musíme rozlišit, zda je nutno vypsat větší i starší příspěvky nebo nové. Aktuální příspěvky můžeme odlišit podle času zadání, nebo podle id, což považuji za lepší. Při každém aktualizování zpráv si tedy uchováme id číslo nejnovějšího příspěvku a při dalším aktualizování si načteme pouze příspvěvky s větším id. Pokud si vyžádáme příspěvek s id=0 načte se jen požadovaný počet nejnovějších zpráv. Skript bude pro jednoduchost generovat přímo HTML kód do stránky.
Náš PHP skript jménem například chat.php může vypadat:
.
Budeme potřebovat 2 AJAXové objekty, aby se nehádaly. První pro získávání příspěvků a druhý pro jejich zápis.
Čtecí objekt bude používat metodu GET a bude posílat pouze ID posledního příspěvku, při prvním zavolání se id=0. Ve stránce bude DIV s id=chtext, do něj budeme vkládat příspěvky. Ajax1 (ve funkci zpravy())získá odpověď serveru na požadavek aktualizování příspěvků, rozdělí ho podle oddělovače |id= na 2 části - text příspěvku a id nejnovějšího příspěvku. Text jako HTML přidá do DIVu chtext. ID si uloží pro další volání.
Zapisovací objekt ajax2 metodou POST pošle PHP skriptu obsah nového příspěvku a čeká na odpověď "ok". Po úspěšném uložení aktualizuje příspěvky.
Aktualizování řídí TimeOut ve funkci aktualizovat, který po uplynutí časového intervalu opět zavolá svou funkci a začíná opět odpočítávat.
Podoba AJAXového JavaScriptu:
Možnosti rozšíření:
. Při jeho tvorbě využijeme AJAX+PHP+MySQL.
Nejprve se zamyslíme co od něj očekáváme:
- Bude ukládat jméno, ip, datum a text zprávy
- Přejeme si aby stahoval pouze nové zprávy
- Chceme však aby bylo zobrazeno i několik předchozích příspěvků

Nyní k serverovým skriptům. Požadujeme 2 operace - výběr příspěvků a zápis. Zápis je jednoduchý jedná se pouze o vložení záznamu do databáze. Výpis příspěvků již bude o malinko složitější. Musíme rozlišit, zda je nutno vypsat větší i starší příspěvky nebo nové. Aktuální příspěvky můžeme odlišit podle času zadání, nebo podle id, což považuji za lepší. Při každém aktualizování zpráv si tedy uchováme id číslo nejnovějšího příspěvku a při dalším aktualizování si načteme pouze příspvěvky s větším id. Pokud si vyžádáme příspěvek s id=0 načte se jen požadovaný počet nejnovějších zpráv. Skript bude pro jednoduchost generovat přímo HTML kód do stránky.
Náš PHP skript jménem například chat.php může vypadat:
/*
připojení k databázi
*/
//získání id, defaultně 0
$lastid=isset($_GET["id"])?$_GET["id"]:0;
//zjištění akce (aktualizovat/poslat), defaultně aktualizovat
$action=isset($_GET["action"])?$_GET["action"]:"aktualizovat";
switch($action){
case "aktualizovat":
//pokud id=0 tak se vybere z databáze 30 nejnovějších příspěvků
if ($lastid<=0) $result = mysql_query("SELECT id, ip, name, timestamp, text FROM chat ORDER BY timestamp desc limit 30");
//jinak příspěvky s id větším než zadaným
else $result = mysql_query("SELECT id, ip, name, timestamp, text FROM chat WHERE chat.id > {$_GET['id']} ORDER BY timestamp desc");
//pro každý příspěvek se vygeneruje HTML kód
while ($zaznam = mysql_fetch_array($result)){
echo "<div title=\"{$zaznam['ip']}\" class=\"styl informací\">".date("d.m H:i:s",$zaznam['timestamp'])." - <strong>{$zaznam['name']}</strong> napsal(a):</div><div class=\"styl příspěvku\">{$zaznam['text']}</div>";
//do proměnné lastid se bude ukládat nejvyšší id
$lastid=($lastid>$zaznam['id'])?$lastid:$zaznam['id'];
}
//na konec je vypsáno nejvyšší aktuální id za oddělovačem, šlo by to samozřejmě udělat i jiným způsobem...
echo "|id=$lastid";
break;
case "poslat":
//pokud jsou vloženy potřebné údaje, je příspěvek vložen do databáze
if (isset($_POST["text"]) and isset($_POST["name"]) and $_POST["text"]!=''){
if (mysql_query("INSERT INTO chat VALUES(0,'". $_SERVER["REMOTE_ADDR"]."','".$_POST["name"]."',".strtotime("now").", '".nl2br(htmlspecialchars($_POST["text"]))."')" ))
//odpověď pokud se zápis do databáze povedl
echo "ok";
}
break;
}
Tak a serverová strana je hotova, můžeme se podívat na klienta a konečně začít s AJAXem
.Budeme potřebovat 2 AJAXové objekty, aby se nehádaly. První pro získávání příspěvků a druhý pro jejich zápis.
Čtecí objekt bude používat metodu GET a bude posílat pouze ID posledního příspěvku, při prvním zavolání se id=0. Ve stránce bude DIV s id=chtext, do něj budeme vkládat příspěvky. Ajax1 (ve funkci zpravy())získá odpověď serveru na požadavek aktualizování příspěvků, rozdělí ho podle oddělovače |id= na 2 části - text příspěvku a id nejnovějšího příspěvku. Text jako HTML přidá do DIVu chtext. ID si uloží pro další volání.
Zapisovací objekt ajax2 metodou POST pošle PHP skriptu obsah nového příspěvku a čeká na odpověď "ok". Po úspěšném uložení aktualizuje příspěvky.
Aktualizování řídí TimeOut ve funkci aktualizovat, který po uplynutí časového intervalu opět zavolá svou funkci a začíná opět odpočítávat.
Podoba AJAXového JavaScriptu:
<script type="text/javascript">
//id příspěvku
var id=0;
//čas obnovování
var timer=5000;
//čtecí a zapisovací objekt
var ajax1 = (window.XMLHttpRequest ? new XMLHttpRequest() : (window.ActiveXObject ? new ActiveXObject("Microsoft.XMLHTTP") : false));
var ajax2 = (window.XMLHttpRequest ? new XMLHttpRequest() : (window.ActiveXObject ? new ActiveXObject("Microsoft.XMLHTTP") : false));
//čtení zpráv
function zpravy(){
if(!ajax1){
alert("Tady AJAX neběží...");
return true;
}
ajax1.onreadystatechange= function () {text(); } ;
//požadavek na čtené nových příspěvků
ajax1.open("GET", "chat.php?action=aktualizovat&id="+id, true);
ajax1.send(null);
return false;
}
//zápis zpráv
function posli(){
if(!ajax2){
alert("Tady AJAX neběží...");
return true;
}
ajax2.onreadystatechange= function () {poslano(); } ;
ajax2.open("POST", "chat.php?action=poslat", true);
ajax2.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
//poslání hodnot z formuláře
ajax2.send("text="+document.form0.text.value+"&name="+document.form0.name.value);
return false;
}
//úkony po poslání zprávy
function poslano(){
if (ajax2.readyState == 4){
if(ajax2.status == 200 || ajax2.status==0){
//pokud se zpráva uložila, dojde k vymazání prvku se zprávou
if(ajax2.responseText=="ok"){
document.form0.text.value="";
zpravy();
}
else alert("Bohužel se nepodařilo zprávu odeslat
");
}
else alert("Chyba: "+ ajax2.status +":"+ ajax2.statusText);
}
}
//vypsání získaných příspěvků
function text(){
var txt;
var param= new Array();
if (ajax1.readyState == 4){
if(ajax1.status == 200 || ajax1.status==0){
//rozdělení textového řetězce na text a id
param=ajax1.responseText.split("|id=");
//výpis do DIVu chtext
document.getElementById("chtext").innerHTML = param[0] + document.getElementById("chtext").innerHTML;
//uložení id nejaktuálnějšího příspěvku
id=param[param.length-1];
}
else alert("Chyba: "+ ajax1.status +":"+ ajax1.statusText);
}
}
//aktualizace příspěvků
function aktualizovat(){
window.setTimeout("aktualizovat()", timer);
zpravy();
}
</script>
Nyní už jen stačí po načtení stránky zavolat funkci aktualizace(), aby náš chat začal fungovat. Ukázka následuje - vypisuje 10 nejnovějších příspěvků, aktualizace probíhá po 30 vteřinách.
Možnosti rozšíření:
- Propojení s databází uživatelů
- Změna rychlosti obnovování podle počtu uživatelů
- Možnost nechat si zobrazit větší historii chatu
- Nahrazování smajlíků a odkazů, nejlépe na straně serveru

