Atualizar
Enquanto continuo recebendo votos positivos, acho razoável lembrar que essa resposta tem 4 anos. A Web cresceu em um ritmo muito rápido, portanto, esteja atento a esta resposta.
Eu tive o mesmo problema recentemente e pesquisei sobre o assunto.
A solução fornecida é chamada de sondagem longa e, para usá-la corretamente, você deve ter certeza de que sua solicitação AJAX possui um tempo limite "grande" e sempre fazer essa solicitação após o término da corrente (tempo limite, erro ou êxito).
Pesquisa Longa - Cliente
Aqui, para manter o código curto, usarei o 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 lembrar que (nos documentos do jQuery ):
No jQuery 1.4.xe abaixo, o objeto XMLHttpRequest estará em um estado inválido se a solicitação atingir o tempo limite; acessar qualquer membro do objeto pode gerar uma exceção. Somente no Firefox 3.0+, solicitações de script e JSONP não podem ser canceladas com um tempo limite; o script será executado mesmo que chegue após o período de tempo limite.
Pesquisa Longa - Servidor
Não está em nenhum idioma específico, mas seria algo como isto:
function handleRequest () {
while (!anythingHappened() || hasTimedOut()) { sleep(2); }
return events();
}
Aqui, hasTimedOut
garantirá que seu código não espere para sempre e anythingHappened
verificará se algum evento ocorreu. O sleep
objetivo é liberar seu thread para fazer outras coisas enquanto nada acontece. O events
retornará um dicionário de eventos (ou qualquer outra estrutura de dados você pode preferir) no formato JSON (ou qualquer outro que você preferir).
Certamente resolve o problema, mas, se você estiver preocupado com escalabilidade e desempenho como eu estava pesquisando, considere outra solução que encontrei.
Solução
Use soquetes!
No lado do cliente, para evitar problemas de compatibilidade, use o socket.io . Ele tenta usar o soquete diretamente e possui fallbacks para outras soluções quando os soquetes não estão disponíveis.
No lado do servidor, crie um servidor usando o NodeJS (exemplo aqui ). O cliente se inscreverá neste canal (observador) criado com o servidor. Sempre que uma notificação precisa ser enviada, ela é publicada neste canal e o assinante (cliente) é notificado.
Se você não gostar desta solução, tente o APE ( Ajax Push Engine ).
Espero ter ajudado.