Sondaggio Ajax

Nel progetto al quale sto lavorando, abbiamo la necessità di sviluppare un'applicazione di chat web, non una chat molto complessa, solo un modo per connettere due persone per parlare di un argomento molto specifico, non abbiamo bisogno di alcun tipo di authentication per uno dei due utenti, non dobbiamo supportre emoticon, avatar o cose del genere.

Alcuni membri del progetto hanno suggerito che potremmo usare XMPP tramite BOSH, ho detto che è come cercare di catturare un pesce con la networking di una barca, e ho proposto un metodo più semplice, come una semplice chat web Ajax / MySQL, ma siamo preoccupati per colpo di performance nel server a causa del polling costante di molte chat aperte contemporaneamente.

Qualcuno ha mai fatto qualcosa del genere? Cosa raccomanderesti?

Potresti anche voler guardare in Comet .

È utilizzato da GTalk, Meebo e molte altre applicazioni di chat . Alcuni anni fa, quando stavo sperimentando, non c'erano molte librerie o dettagli sull'architettura del server per implementarlo, ma sembra che ci siano molte più cose da fare adesso.

Dai un'occhiata al progetto cometd per maggiori informazioni tecniche.

Cosa raccomanderesti?

XMPP tramite BOSH

Non è necessario inventare il proprio formato dei messaggi e il protocollo di trasporto quando qualcuno lo ha fatto. Se ci provi, crescerà lentamente fino a diventare altrettanto complesso di BOSH, ma senza il vantaggio del supporto o della standardizzazione delle librerie di terze parti.

Se non ti piace l'idea del polling HTTP, potresti avere un filmato Flash sulla pagina della chat che ha una connessione costante con alcuni deamon sul server, il filmato Flash invocherà quindi le funzioni JavaScript sul client per l'aggiornamento la chat come nuovi messaggi arriva. (A less che tu non voglia un'interface Flash per la tua chat ..)

Potresti anche voler guardare in Comet.

Pensavo che tutti usassero cometd per questo genere di cose.

BOSH è uno standard per il trasporto di XMPP su HTTP. Coinvolge Comet per spingere i dati al cliente.

C'è un ottimo server per gestire il messaggio che spinge dal server al browser (chiamato Comet ) – Orbited . Si integra facilmente con altre tecnologie (Django, Rails, PHP ecc.) Proprio come memcached.

Dovresti davvero controllarlo se vuoi gestire un carico serio. Altrimenti, il semplice sondaggio Ajax è il modo migliore.

Il trucco è rendersi conto che l'unica volta che la tua app ha bisogno di invocare CGI sul server è quando qualcuno dice qualcosa. Per i sondaggi regolari, esegui il polling di una pagina statica che il tuo script CGI aggiorna each volta che c'è una nuova chat. Utilizza le richieste HEAD, confronta i timestamp con quelli visti l'ultima volta e fai un GET completo solo quando questi cambiano. Ho una semplice applicazione di chat ingenua implementata in questo modo, e l'utilizzo del carico e della width di banda è trascurabile per le poche decine di utenti simultanei che abbiamo.

Ho fatto la stessa cosa qualche mese fa e mi sono divertita a giocare con i concetti. In realtà ho usato la tecnica del frame infinito invece del polling.

Il codice seguente è il mio file js "cometa" che contiene i concetti generali necessari per get una configuration di "chat party".

function Comet(key) { var random = key; var title = 'Comet'; var connection = false; var iframediv = false; var browserIsIE = /*@[email protected]*/false; var blurStatus = false; var tmpframe = document.createElement('iframe'); var nl = '\r\n'; this.initialize = function() { if (browserIsIE) { connection = new ActiveXObject("htmlfile"); connection.open(); connection.write("<html>"); connection.write("<script>document.domain = '"+document.domain+"'"); connection.write("</html>"); connection.close(); iframediv = connection.createElement("div"); connection.appendChild(iframediv); connection.parentWindow.comet = comet; iframediv.innerHTML = "<iframe id='comet_iframe' src='./comet.aspx?key="+random+"'></iframe>"; } else { connection = document.createElement('iframe'); connection.setAttribute('id', 'comet_iframe'); iframediv = document.createElement('iframe'); iframediv.setAttribute('src', './comet.aspx?key='+random); connection.appendChild(iframediv); document.body.appendChild(connection); } } // this function is called from the server to keep the connection alive this.keepAlive = function () { if (!browserIsIE) { mozillaHack(); } } // this function is called from the server to update the client this.updateClient = function (value) { var outputDiv = document.getElementById('output'); outputDiv.value = value + nl + outputDiv.value; if (blurStatus == true) { document.title = value; } if (!browserIsIE) { mozillaHack(); } } this.onUnload = function() { if (connection) { // this will release the iframe to prevent problems with IE when reloading the page connection = false; } } this.toggleBlurStatus = function(bool) { blurStatus = bool; } this.resetTitle = function() { document.title = title; } function mozillaHack() { // this hack will fix the hour glass and loading status for Mozilla browsers document.body.appendChild(tmpframe); document.body.removeChild(tmpframe); } } 

Pensavo che tutti usassero cometd per questo genere di cose.

Sono d'accordo con John. Ma c'era un'altra domanda a cui non è stata data risposta.
Ho fatto questo, ma invece di usare un database abbiamo usato un file flat, alla fine ha storpiato il server, ma non è stato fino a quando non abbiamo ~ 450 utenti attivi, e se lo avessimo fatto con un database probabilmente sarebbe andato meglio.
Questo è stato fatto su un account di hosting di base da Godaddy.

Modifica: BTW Godaddy sembrava less divertente quando ho ricevuto la telefonata.

Penso che il polling sia l'approccio più semplice e lo consiglierei per primo. Se il carico diventa un problema inizia, esaminando le tecniche più complicate. Una buona discussione sui pro e contro sono qui – http://www.infoq.com/news/2007/07/pushvspull
http://ajaxian.com/archives/a-report-on-push-versus-pull

Checkout Speeqe . È una soluzione open-source per chat room basate sul Web che utilizza BOSH e XMPP dietro le quinte.

Ho appena trovato questo post, è vecchio, ma il concetto di sondaggio dà problemi a molte persone. Quindi metterò un esempio di implementazione qui. Ma prima di dartelo, dovrei darti un consiglio che mi ha fatto impazzire qualche tempo fa:

Quando si esegue il sondaggio, è necessario occuparsi del comportmento delle sessioni ( condizioni di gara ). Per semplificare: se apri una session, il file di session viene bloccato fino alla chiusura della session per evitare che 2 thead scrivano dati diversi all'interno di essa. Quindi, se hai bisogno di una session per controllare se un utente è loggato o così, chiudi sempre la session prima del polling.

La mia demo ti offre un esempio di implementazione di polling in PHP. Non userò un database, ma un file. Quando fai clic sul button di polling, entrerai nel ciclo e finché il file non verrà modificato, rimarrai il polling. Quando compili il module e fai clic su Rilascia, ciò che hai digitato verrà salvato nel file. Il tempo di modifica del file cambierà così il polling si fermerà.

Suggerimento: usa uno strumento come Firebug per vedere cosa succede.

Ora parliamo in una lingua migliore del mio inglese:

 <?php // For this demo if (file_exists('poll.txt') == false) { file_put_contents('poll.txt', ''); } if (isset($_GET['poll'])) { // Don't forget to change the default time limit set_time_limit(120); date_default_timezone_set('Europe/Paris'); $time = time(); // We loop until you click on the "release" button... $poll = true; $number_of_tries = 1; while ($poll) { // Here we simulate a request (last mtime of file could be a creation/update_date field on a base) clearstatcache(); $mtime = filemtime('poll.txt'); if ($mtime > $time) { $result = htmlentities(file_get_contents('poll.txt')); $poll = false; } // Of course, else your polling will kill your resources! $number_of_tries++; sleep(1); } // Outputs result echo "Number of tries : {$number_of_tries}<br/>{$result}"; die(); } // Here we catch the release form if (isset($_GET['release'])) { $data = ''; if (isset($_GET['data'])) { $data = $_GET['data']; } file_put_contents('poll.txt', $data); die(); } ?> <!-- click this button to begin long-polling --> <input id="poll" type="button" value="Click me to start polling" /> <br/><br/> Give me some text here : <br/> <input id="data" type="text" /> <br/> <!-- click this button to release long-polling --> <input id="release" type="button" value="Click me to release polling" disabled="disabled" /> <br/><br/> Result after releasing polling : <div id="result"></div> <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script> <script type="text/javascript"> // Script to launch polling $('#poll').click(function() { $('#poll').attr('disabled', 'disabled'); $('#release').removeAttr('disabled'); $.ajax({ url: 'poll.php', data: { poll: 'yes' // sets our $_GET['poll'] }, success: function(data) { $('#result').html(data); $('#poll').removeAttr('disabled'); $('#release').attr('disabled', 'disabled'); } }); }); // Script to release polling $('#release').click(function() { $.ajax({ url: 'poll.php', data: { release: 'yes', // sets our $_GET['release'] data: $('#data').val() // sets our $_GET['data'] } }); }); </script> 

Puoi provarlo qui