Aggiornare
Mentre continuo a ricevere voti su questo, penso che sia ragionevole ricordare che questa risposta ha 4 anni. Il Web è cresciuto molto rapidamente, quindi tieni presente questa risposta.
Ho avuto lo stesso problema di recente e ho studiato l'argomento.
La soluzione fornita si chiama polling lungo e per utilizzarla correttamente è necessario assicurarsi che la richiesta AJAX abbia un timeout "grande" e di effettuare sempre questa richiesta dopo la fine corrente (timeout, errore o esito positivo).
Polling lungo - Client
Qui, per mantenere il codice breve, userò jQuery:
function pollTask() {
$.ajax({
url: '/api/Polling',
async: true, // by default, it's async, but...
dataType: 'json', // or the dataType you are working with
timeout: 10000, // IMPORTANT! this is a 10 seconds timeout
cache: false
}).done(function (eventList) {
// Handle your data here
var data;
for (var eventName in eventList) {
data = eventList[eventName];
dispatcher.handle(eventName, data); // handle the `eventName` with `data`
}
}).always(pollTask);
}
È importante ricordare che (dai documenti jQuery ):
In jQuery 1.4.x e precedenti, l'oggetto XMLHttpRequest sarà in uno stato non valido se la richiesta scade; l'accesso a qualsiasi membro dell'oggetto può generare un'eccezione. Solo in Firefox 3.0+, le richieste di script e JSONP non possono essere annullate da un timeout; lo script verrà eseguito anche se arriva dopo il periodo di timeout.
Polling lungo - Server
Non è in una lingua specifica, ma sarebbe qualcosa del genere:
function handleRequest () {
while (!anythingHappened() || hasTimedOut()) { sleep(2); }
return events();
}
Qui, hasTimedOut
ci assicureremo che il tuo codice non aspetti per sempre, e anythingHappened
controllerà se qualche evento è successo. Lo scopo sleep
è di rilasciare il tuo thread per fare altre cose mentre non succede nulla. Il events
restituirà un dizionario di eventi (o di qualsiasi altra struttura dati si può preferire) in formato JSON (o qualsiasi altro si preferisce).
Risolve sicuramente il problema, ma, se sei preoccupato per la scalabilità e le prestazioni come ero durante la ricerca, potresti prendere in considerazione un'altra soluzione che ho trovato.
Soluzione
Usa le prese!
Sul lato client, per evitare problemi di compatibilità, utilizzare socket.io . Cerca di utilizzare direttamente il socket e presenta fallback su altre soluzioni quando i socket non sono disponibili.
Sul lato server, creare un server utilizzando NodeJS (esempio qui ). Il client si abbonerà a questo canale (osservatore) creato con il server. Ogni volta che deve essere inviata una notifica, questa viene pubblicata in questo canale e il sottoscrittore (client) viene avvisato.
Se non ti piace questa soluzione, prova APE ( Ajax Push Engine ).
Spero di averti aiutato.