Twitter status:

    Ajax Chat

    come promesso eccomi con un tutorial in sfrutteremo la potenza di Ajax con un linguaggio server-side per realizzare una semplice chat-room.

    Alla fine del tutorial avremo:

    • un file index.html ed un file chat.php
    • il file index.html leggerà il contenuto di una textbox e li invierà a chat.php
    • chat.php scriverà il contenuto nel file chat.txt
    • 2 http_request , una per controllare il contenuto e l’altra per inviare il messaggio

    Puoi vedere il risultato qui.

    Iniziamo dal codice php:

    /* piccolo antispam per bloccare parole o ip */
    $spam[] = “badword1″;
    $spam[] = “badword2″;
    $blockip[] = “1.1.1.1″;
    $msg = $_REQUEST["m"];
    if ($msg != “”) {
    /* Controllo antispam */
    if (strlen($msg) < 2) { die(); }
    if (strlen($msg) > 3) {
    if (strtoupper($msg) == $msg) { die(); }
    }
    if (strlen($msg) > 150){ die(); }
    if (strlen($msg) > 15) {
    if (substr_count($msg, substr($msg, 6, 8 )) > 1) { die(); }
    }
    foreach ($blockip as $a) {
    if ($_SERVER["REMOTE_ADDR"] == $a) { die(); }
    }
    $mystring = strtoupper($msg);
    foreach ($spam as $a) {
    if (strpos($mystring, strtoupper($a)) === false) {
    /* La stringa ha passato il controlo antispam */
    } else {
    die();
    }
    }

    In pratica pochi controlli per verificare che una stringa non sia una delle parole che abbiamo inserito nel filtro antispam o che l’indirizzo non sia tra uno di quelli bloccati.

    Andiamo avanti:

    /* prepariamo il contenuto */
    $fn = "chat.txt";
    $maxlines = 20;
    $handle = fopen ($fn, 'r');
    $chattext = fread($handle, filesize($fn));
    fclose($handle);
    $arr1 = explode("\n", $chattext);
    if (count($arr1) > $maxlines) {
    /* Limitiamo la lunghezza della stringa */
    $arr1 = array_reverse($arr1);
    for ($i=0; $i<$maxlines; $i++) { $arr2[$i] = $arr1[$i]; }
    $arr2 = array_reverse($arr2);
    } else {
    $arr2 = $arr1;
    }
    $chattext = implode("\n", $arr2);
    /* Altro piccolo controllo antispam */
    if (substr_count($chattext, $msg) > 2) { die(); }
    /* Scriviamo il tutto */
    $out = $chattext . $msg . “\n”;
    $out = str_replace(”\’”, “‘”, $out);
    $out = str_replace(”\\\”", “\”", $out);
    $handle = fopen ($fn, ‘w’);
    fwrite ($handle, $out);
    fclose($handle);
    }
    ?>

    E questo era il semplice script per scrivere il file, niente di complicato, si inserisce la stringa, se è maggiore di $maxlines la si “taglia” e la si appende al file di testo.

    ed ora il file html contentente il javascript che permette ad Ajax di funzionare.

    Vediamo lo script:

    <script type="text/javascript">
    /* Richiesta Ajax */
    var http_request=false;
    var http_request2=false;
    var intUpdate;
    function ajax_request(url){http_request=false;
    if(window.XMLHttpRequest){http_request=new XMLHttpRequest();
    if(http_request.overrideMimeType){http_request.overrideMimeType('text/xml');
    }
    }
    else if(window.ActiveXObject){try{http_request=new ActiveXObject("Msxml2.XMLHTTP");
    }
    catch(e){
    try{http_request=new ActiveXObject("Microsoft.XMLHTTP");
    }catch(e){}}}
    if(!http_request){alert('Mi fermo : ( Impossibile creare una istanza XMLHTTP');
    return false;
    }
    http_request.onreadystatechange=alertContents;
    http_request.open('GET',url,true);http_request.send(null);
    }
    function alertContents(){
    if(http_request.readyState==4)
    {
    if(http_request.status==200)
    {rec_response(http_request.responseText);
    }else{}
    }
    }

    questo codice dovrebbe essere familiare se avete letto il tutorial su Ajax base, altrimenti fatelo :D
    Comunque crea l’istanza di XMLHTTP a seconda del browser e con un minimo di gestione degli errori

    Andiamo avanti e vediamo il metodo per leggere la richiesta Ajax:

    /* Lettura richiesta Ajax */
    function ajax_request2(url){http_request2=false;
    if(window.XMLHttpRequest){
    http_request2=new XMLHttpRequest();
    if(http_request2.overrideMimeType){http_request2.overrideMimeType('text/xml');
    }
    }
    else if(window.ActiveXObject){
    try{http_request2=new ActiveXObject("Msxml2.XMLHTTP");
    } catch(e){
    try{http_request2=new ActiveXObject("Microsoft.XMLHTTP");
    } catch(e){}
    }
    }
    if(!http_request2){alert('Mi fermo : ( Impossibile creare una istanza XMLHTTP');
    return false;
    }
    http_request2.onreadystatechange=alertContents2;
    http_request2.open('GET',url,true);
    http_request2.send(null);
    }
    function alertContents2(){
    if(http_request2.readyState==4){
    if(http_request2.status==200){
    rec_chatcontent(http_request2.responseText);
    }else{}
    }
    }

    anche questo dovrebbe esserervi familiare se avete letto il tutorial precendete.

    ora vediamo il codice che riguarda la chat vera e propria

    /* Codice riguardante la chat */
    waittime=2000;
    intUpdate=window.setTimeout("read_cont()", waittime);
    chatwindow.value = "connecting...";
    function display_msg(msg1) {
    /* riempio la textarea con il contenuto */
    chatwindow.value = msg1;
    }
    function write_msg(msg1) {
    ajax_request("chat.php?m=" + escape(msg1));
    }
    function submit_msg() {
    /* invio il mio messaggio*/
    write_msg(chatmsg.value);
    chatmsg.value="";
    }
    function rec_response(str1) {
    /* la risposta qui è data dallo script php*/
    }
    function rec_chatcontent(cont1) {
    if (cont1 != "") {
    out1 = "";
    /* capovolgo i messaggi in modo da mostra prima l'ultimo inviato */
    while (cont1.indexOf("\n") > -1) {
    out1 = cont1.substr(0, cont1.indexOf("\n")) + "\n" + out1;
    cont1 = cont1.substr(cont1.indexOf("\n") + 1);
    }
    out1 = unescape(out1);
    if (chatwindow.value != out1) { display_msg(out1); }
    intUpdate=window.setTimeout("read_cont()", waittime);
    }
    }
    function read_cont() {
    /* funzione per prvenire il buffering */
    zeit = new Date();
    ms = (zeit.getHours() * 24 * 60 * 1000) + (zeit.getMinutes() * 60 * 1000) + (zeit.getSeconds() * 1000) + zeit.getMilliseconds();
    ajax_request2("chat.txt?x=" + ms);
    }
    function keyup(arg1) {
    if (arg1 == 13) { submit_msg(); } }
    </script>

    La funzione dispay_msg è ovvia, in quanto non fà altro che aggiungere alla textarea il messaggio digitato nel form.
    La funzione write_msg chiama la nostra funzione Ajax la quale a sua volta richiede la pagina con lo script php per la scrittura.
    submit_msg è anch’essa banale in quanto non fà altro che chiamare write_msg al momento dell’invio.
    Con la funzione rec_chatcontent mostro i messaggi, in ordine inverso presenti sul file chat.txt
    Ed infine il codice html per il form (con un minimo di CSS):
    <html>
    <head>
    <title>room1</title>
    </head>
    <body>
    <textarea id="chatwindow" rows="10" cols="80" style="border:1px solid #aaaaaa; padding:4px;" readonly></textarea><br>
    <input id="chatmsg" type="text" size="20" style="border:1px solid #aaaaaa;" onkeyup="keyup(event.keyCode);"> <input type="button" value="ok" onclick="submit_msg()" style="cursor:pointer;border:1px solid gray;">
    </body>
    </html>

    Spero di essere stato utile ancora una volta con questo esempio, scusate se non è molto commentato ma non mi piace scrivere articolo troppo lunghi, magari la prossima volta penserò ad un tutorial “a puntate”.
    Comunque per qualunque delucidazione non esitate a chiedere attraverso il blog.

    14 Responses to “Ajax Chat”

    • elysaweb Says:

      Ciao! Io sto creando una chat in php e mysql. Attualmente uso un iframe per visualizzare i messaggi, che recupero tramite una query dal database, ma mi hanno consigliato di usare ajax al posto dell’iframe. Io conosco abbastanza bene php, ma non ne so proprio nulla di ajax. Potresti dirmi come fare? In ogni caso ora provo a leggermi la tua guida base, magari ne capisco qualcosa di più!

      Grazie intanto!

    • slacko Says:

      Ajax sicuramente è una scelta migliore rispetto all’ IFrame (soliti problemi legati all’accessibilità ed all’indicizzazione); la funzione presentata del tutorial è abbastanza semplice, nel tuo caso basta usare il database (adattando il codice php) invece del file di testo usato da me e lasciare il codice javascript così com’è.

    • lorenzo Says:

      Ho provato in locale lo script…
      ma stranamente non mi parte…
      non mi scrive il testo nella pagina…

      se ti interessa io ho un pc Linux Ubuntu (quindi il server locale è linux).

      grazie

    • slacko Says:

      Non ricevi nessun errore o warning dall’interprete PHP?

    • lorenzo Says:

      no, niente…
      compare tutto come normale, ma quando scrivo un messaggio e lo invio non viene scritto nell file!

    • lorenzo Says:

      neanche un errore…

    • lorenzo Says:

      non mi sai dire nulla?
      help!
      please :’(

    • slacko Says:

      così senza un minimo di debug no, provato con firebug a vedere se c’è qualche cosa di strano nella richiesta ajax?

    • lorenzo Says:

      come faccio?
      parli arabo

      PS:uso firefox (sono su Linux!)

    • lorenzo Says:

      ti do il link del mio “server”
      magari vedi come funziona direttamente dal mio PC:
      http://87.25.75.173/wii/
      fammi sapere

    • lorenzo Says:

      io devo staccare,
      il mio “server” con quel “link” che ti ho dato, non sarà più valido, non funzionerà .

      ti chiedo comunque di contattarmi (se puoi) per risolvere il probla:
      email:koalalorenzo@gmail.com

    • Kodyfile Says:

      Ciao, non ho provato il tuo script ma arrivo a questo blog perchè ho delle chat in ajax, fatte da me, sul mio sito.

      Ho due grossi problemi, magari qualcuno, o tu stesso, ne siete già incappati e sapete dirmi come risolvere.

      1. Sia su FF che IE molto spesso si mangia le frasi, cioè quando un utente mi clicca il tasto invia capita che la frase non venga visualizzata nella chat. Postmetto che bufferizzo anche io ma con un algoritmo più semplice tipo un rand() * date()

      2. Su FF Premettendo che ho un puntatore in sessione che mi serve per sapere a quale linea del file sono arrivato, così non mostro sempre tutto il contenuto quando un utente esce e rientra dalla chat, a volte capita che la chat riscriva tutto il file da capo.

      2b. Su FF io uso dei comandi di DOM per creare degli che vado ad appendere in una struttura a child capita a volte che mi triplichi o duplichi il child, anche se all’interno del file la frase è scritta 1 sola volta.

      Se sapete darmi maggiori info su questi problemi ve ne sono immensamente grato.

      Ciao,
      Kody. :)

    • slacko.org Ajax e POST, una chiarificazione » Says:

      [...] le applicazioni sviluppate in Ajax utilizzano il metodo GET come visto ad esempio qui. In questi giorni sto sviluppando un piccolo client per Ping.fm, le cui API accettano solo [...]

    • Pencil case Says:

      Interessante…
      Senti..visto ke te ne intendi..ti kiedo due cose..
      1: sai quale codice usare per velocizzare una chat?
      2: il codice per bloccare una chat?

      grazie :)

    Leave a Reply