Olá Pessoal !
Como mostrei a forma de se fazer um Long Polling utilizando Node.JS ( Long Polling com Node.JS ) , irei mostrar agora a forma de se fazer com PHP.
Importante !
Funcionar funciona, apesar de não ser tão eficiente quanto ao long polling feito utilizando node.js, não foram testados os efeitos colaterais no servidor, tais como desempenho e concorrência de uso, afinal estamos utilizando PHP.
A Técnica
Bom, para começar eu gostaria que vocês lessem o post do Long Polling com Node.JS para entender um pouco mais da técnica utilizada, o que na verdade só é uma técnica e aplicando o que foi proposto por ela:
- Abrir a conexão e não deixar que esta seja fechada sem resposta
- Se a conexão for fechada por algum motivo, tentar reabrir
- Não fechar a conexão até ter uma resposta esperada
Vocês irão ter um Long Polling com sucesso, então vamos lá .!
Lógica, Codificação
Criei quatro arquivos { “index.php” , “data.txt” , “server.php” , “client.js” } o data.txt contém os dados que serão mostrados, mas antes disso será feita uma comparação lógica, que se baseia em NÃO emitir uma resposta se : ‘os dados do data.txt estiverem vazios, se o conteúdo do data.txt for igual ao conteúdo requisitado’
Conteúdo requisitado ? quando recebemos uma resposta do servidor, que obviamente só vamos receber se houver conteúdo, nos capturamos o que foi retornado e enviamos por query string de volta ; Por que ? para comparar se o conteúdo atual ou futuro do data.txt é diferente, pois não vamos responder ou perguntar algo que já sabemos, lembrando que a mesma coisa vale para um banco de dados.
Nosso código PHP ficaria assim:
<?php while ( true ) { $data = file_get_contents ( 'data.txt' ) ; $requested = isset ( $_GET [ 'content' ] ) ? $_GET [ 'content' ] : null ; if ( strlen ( $data ) > 0 && $requested !== $data ) { echo $data ; break ; } else { sleep ( 2 ) ; // vamos dar um intervalo ! continue ; } }
O que fizemos ? iniciamos um loop infinito, logicamente se ele não for parado a requisição nunca vai terminar, a mesma coisa vale pra quando entramos na página que contém esse código ( server.php ) , e então lemos o conteúdo do arquivo, e procuramos pelo índice content na query string , duas comparações simples ( se a quantidade de caracteres de $data for maior que zero e se $requested for diferente de $data que é o conteúdo do text, emitimos a resposta e paramos o loop , nesse caso a requisição é fechada, feito isso o resto é simples.
Agora, o lado do cliente ( jscript ) , basta criar uma função que é responsável por enviar a requisição para ‘server.php’, e quando esta for fechada ( Http Code 200 ) , criamos a requisição novamente .. e assim por diante ( recursividade )
$ ( document ).ready ( function ( ) { $ ( '#ready' ).on ( 'click' , function ( ) { startPolling = function ( content ) { content === undefined || $ ( '#response' ).html ( content ) ; var qs = { 'content' : content } ; $.get ( 'server.php' , qs , function ( data ) { startPolling ( data ) ; } ) ; } ; startPolling ( undefined ) ; } ) ; } ) ;
Só precisamos disso .. bem simples e direto , a unica coisa que tem de demais no código acima, é a recursividade, como eu disse que faz parte da técnica, a conexão precisa ser reaberta caso fechada, e ela só é fechada quando temos a resposta esperada , para testar basta criar um arquivo html e colocar o seguinte código
<html> <head> <script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script> <script type="text/javascript" src="client.js"></script> </head> <body> <input type="button" value="ready" id="ready"> <div id="response"></div> </body> </html>
Isso é tudo .. agora façam seus testes, não apliquem uma técnica dessa pra algo que possa ser resolvido de outra forma, estude outras maneiras e principalmente, avaliem o custo benefício de cada uma delas, o que foi demonstrado acima funciona, você evita ficar enviando requisições ao servidor quando ele está respondendo o que você não quer , me faz lembrar o burro do shrek .
Abraços, e boa sorte !