A maneira como o Facebook faz isso é bastante interessante.
Um método comum de fazer essas notificações é pesquisar um script no servidor (usando AJAX) em um determinado intervalo (talvez a cada poucos segundos), para verificar se algo aconteceu. No entanto, isso pode consumir bastante a rede e muitas vezes você faz solicitações inúteis, porque nada aconteceu.
A maneira como o Facebook faz isso é usar a abordagem do cometa, em vez de pesquisar em um intervalo, assim que uma pesquisa é concluída, ela emite outra. No entanto, cada solicitação para o script no servidor tem um tempo limite extremamente longo, e o servidor só responde à solicitação depois que algo acontece. Você pode ver isso acontecendo se você abrir a guia Console do Firebug enquanto estiver no Facebook, com solicitações para um script que podem levar alguns minutos. Na verdade, é bastante engenhoso, pois esse método reduz imediatamente o número de solicitações e a frequência com que você precisa enviá-las. Agora você efetivamente possui uma estrutura de eventos que permite ao servidor 'acionar' eventos.
Por trás disso, em termos do conteúdo real retornado dessas pesquisas, é uma resposta JSON, com o que parece ser uma lista de eventos e informações sobre eles. É reduzido, porém, é um pouco difícil de ler.
Em termos de tecnologia atual, o AJAX é o caminho a seguir aqui, porque você pode controlar o tempo limite da solicitação e muitas outras coisas. Eu recomendaria (clichê de estouro de pilha aqui) usando o jQuery para fazer o AJAX, isso levará muitos problemas de compatibilidade cruzada. Em termos de PHP, você pode simplesmente pesquisar uma tabela de banco de dados de log de eventos em seu script PHP e retornar ao cliente apenas quando algo acontecer? Espero, existem muitas maneiras de implementar isso.
Implementando:
Lado do servidor:
Parece haver algumas implementações de bibliotecas de cometas no PHP, mas, para ser honesto, é realmente muito simples, algo talvez como o seguinte pseudocódigo:
while(!has_event_happened()) {
sleep(5);
}
echo json_encode(get_events());
A função has_event_happened apenas verificaria se algo havia acontecido em uma tabela de eventos ou algo assim, e a função get_events retornaria uma lista das novas linhas da tabela? Depende do contexto do problema realmente.
Não se esqueça de alterar o tempo máximo de execução do PHP, caso contrário o tempo limite será excedido!
Lado do Cliente:
Dê uma olhada no plugin jQuery para fazer a interação do cometa:
Dito isto, o plugin parece adicionar um pouco de complexidade, é realmente muito simples para o cliente, talvez (com jQuery) algo como:
function doPoll() {
$.get("events.php", {}, function(result) {
$.each(result.events, function(event) { //iterate over the events
//do something with your event
});
doPoll();
//this effectively causes the poll to run again as
//soon as the response comes back
}, 'json');
}
$(document).ready(function() {
$.ajaxSetup({
timeout: 1000*60//set a global AJAX timeout of a minute
});
doPoll(); // do the first poll
});
A coisa toda depende muito de como a arquitetura existente é montada.
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:
É importante lembrar que (nos documentos do jQuery ):
Pesquisa Longa - Servidor
Não está em nenhum idioma específico, mas seria algo como isto:
Aqui,
hasTimedOut
garantirá que seu código não espere para sempre eanythingHappened
verificará se algum evento ocorreu. Osleep
objetivo é liberar seu thread para fazer outras coisas enquanto nada acontece. Oevents
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.
fonte
hasTimedOut()
?De acordo com uma apresentação de slides sobre o sistema de mensagens do Facebook, o Facebook usa a tecnologia do cometa para "enviar" mensagens aos navegadores da web. O servidor cometa do Facebook é construído no mochiweb de servidor da Web Erlang, de código aberto.
Na figura abaixo, a frase "agrupamentos de canais" significa "servidores cometas".
Muitos outros sites grandes constroem seu próprio servidor cometa, porque existem diferenças entre as necessidades de cada empresa. Mas construir seu próprio servidor de cometa em um servidor de cometa de código aberto é uma boa abordagem.
Você pode experimentar o icomet , um servidor cometa C1000K C ++ construído com libevent. O icomet também fornece uma biblioteca JavaScript, é fácil de usar tão simples quanto:
O icomet suporta uma ampla variedade de navegadores e sistemas operacionais, incluindo Safari (iOS, Mac), IEs (Windows), Firefox, Chrome etc.
fonte
O Facebook usa MQTT em vez de HTTP. O envio é melhor que a pesquisa. Por meio do HTTP, precisamos pesquisar o servidor continuamente, mas por meio do servidor MQTT envia a mensagem aos clientes.
Comparação entre MQTT e HTTP: http://www.youtube.com/watch?v=-KNPXPmx88E
Nota: minhas respostas são mais adequadas para dispositivos móveis.
fonte
Uma questão importante com pesquisas longas é o tratamento de erros. Existem dois tipos de erros:
A solicitação pode atingir o tempo limite. Nesse caso, o cliente deve restabelecer a conexão imediatamente. Este é um evento normal em pesquisas longas, quando nenhuma mensagem chegou.
Um erro de rede ou um erro de execução. Este é um erro real que o cliente deve aceitar e aguardar normalmente pelo servidor voltar on-line.
O principal problema é que, se o manipulador de erros restabelecer a conexão imediatamente também para um erro do tipo 2, os clientes farão o DOS no servidor.
Ambas as respostas com amostra de código perdem isso.
fonte