{"id":867,"date":"2012-05-03T20:36:54","date_gmt":"2012-05-03T20:36:54","guid":{"rendered":"http:\/\/leonardocotta.com.br\/blog\/?p=867"},"modified":"2012-05-03T20:36:54","modified_gmt":"2012-05-03T20:36:54","slug":"long-polling-com-php","status":"publish","type":"post","link":"https:\/\/leonardocotta.com.br\/?p=867","title":{"rendered":"Long Polling com #PHP"},"content":{"rendered":"<p style=\"font-family:arial, sans-serif;line-height:normal;background-color:#ffffff;\">Ol\u00e1 Pessoal !<br \/>\nComo mostrei a forma de se fazer um Long Polling utilizando Node.JS (\u00a0<span style=\"color:#1155cc;\">Long Polling com<\/span> <span style=\"color:#1155cc;\">Node.JS<\/span>\u00a0) , irei mostrar agora a forma de se fazer com PHP.<\/p>\n<h2 style=\"font-family:arial, sans-serif;line-height:normal;background-color:#ffffff;\">Importante !<\/h2>\n<p style=\"font-family:arial, sans-serif;line-height:normal;background-color:#ffffff;\">Funcionar funciona, apesar de n\u00e3o ser t\u00e3o eficiente quanto ao long polling feito utilizando node.js, n\u00e3o foram testados os efeitos colaterais no servidor, tais como desempenho e concorr\u00eancia de uso, afinal estamos utilizando PHP.<\/p>\n<h2 style=\"font-family:arial, sans-serif;line-height:normal;background-color:#ffffff;\">A T\u00e9cnica<\/h2>\n<p style=\"font-family:arial, sans-serif;line-height:normal;background-color:#ffffff;\">Bom, para come\u00e7ar eu gostaria que voc\u00eas lessem o post do Long Polling com Node.JS para entender um pouco mais da t\u00e9cnica utilizada, o que na verdade s\u00f3 \u00e9 uma t\u00e9cnica e aplicando o que foi proposto por ela:<\/p>\n<ul style=\"font-family:arial, sans-serif;line-height:normal;background-color:#ffffff;\">\n<li>Abrir a conex\u00e3o e n\u00e3o deixar que esta seja fechada sem resposta<\/li>\n<li>Se a conex\u00e3o for fechada por algum motivo, tentar reabrir<\/li>\n<li>N\u00e3o fechar a conex\u00e3o at\u00e9 ter uma resposta esperada<\/li>\n<\/ul>\n<p style=\"font-family:arial, sans-serif;line-height:normal;background-color:#ffffff;\">Voc\u00eas ir\u00e3o ter um Long Polling com sucesso, ent\u00e3o vamos l\u00e1 .!<\/p>\n<h2 style=\"font-family:arial, sans-serif;line-height:normal;background-color:#ffffff;\">L\u00f3gica, Codifica\u00e7\u00e3o<\/h2>\n<p style=\"font-family:arial, sans-serif;line-height:normal;background-color:#ffffff;\">Criei quatro arquivos { \u201cindex.php\u201d , \u201cdata.txt\u201d , \u201cserver.php\u201d , \u201cclient.js\u201d } o data.txt cont\u00e9m os dados que ser\u00e3o mostrados, mas antes disso ser\u00e1 feita uma compara\u00e7\u00e3o l\u00f3gica, que se baseia em N\u00c3O emitir uma resposta se : \u2018os dados do data.txt estiverem vazios, se o conte\u00fado do data.txt for igual ao conte\u00fado requisitado\u2019<\/p>\n<p style=\"font-family:arial, sans-serif;line-height:normal;background-color:#ffffff;\">Conte\u00fado requisitado ? quando recebemos uma resposta do servidor, que obviamente s\u00f3 vamos receber se houver conte\u00fado, nos capturamos o que foi retornado e enviamos por query string de volta ; Por que ? para comparar se o conte\u00fado atual ou futuro do data.txt \u00e9 diferente, pois n\u00e3o vamos responder ou perguntar algo que j\u00e1 sabemos, lembrando que a mesma coisa vale para um banco de dados.<\/p>\n<p style=\"font-family:arial, sans-serif;line-height:normal;background-color:#ffffff;\">Nosso c\u00f3digo PHP ficaria assim:<\/p>\n<pre style=\"font-size:11px;line-height:normal;background-color:#ffffff;\">&lt;?php\n       while ( true ) {\n              $data = file_get_contents ( 'data.txt' ) ;\n              $requested = isset ( $_GET [ 'content' ] ) ? $_GET [ 'content' ] : null ;\n              if ( strlen ( $data ) &gt; 0 &amp;&amp; $requested !== $data ) {\n                     echo $data ;\n                     break ;\n              } else {\n                     sleep ( 2 ) ; \/\/ vamos dar um intervalo !\n                     continue ;\n              }\n       }<\/pre>\n<p style=\"font-family:arial, sans-serif;line-height:normal;background-color:#ffffff;\">O que fizemos ? iniciamos um loop infinito, logicamente se ele n\u00e3o for parado a requisi\u00e7\u00e3o nunca vai terminar, a mesma coisa vale pra quando entramos na p\u00e1gina que cont\u00e9m esse c\u00f3digo ( server.php ) , e ent\u00e3o lemos o conte\u00fado do arquivo, e procuramos pelo \u00edndice content na query string , duas compara\u00e7\u00f5es simples ( se a quantidade de caracteres de $data for maior que zero e se $requested for diferente de $data que \u00e9 o conte\u00fado do text, emitimos a resposta e paramos o loop , nesse caso a requisi\u00e7\u00e3o \u00e9 fechada, feito isso o resto \u00e9 simples.<\/p>\n<p style=\"font-family:arial, sans-serif;line-height:normal;background-color:#ffffff;\">Agora, o lado do cliente ( jscript ) , basta criar uma fun\u00e7\u00e3o que \u00e9 respons\u00e1vel por enviar a requisi\u00e7\u00e3o para \u2018server.php\u2019, e quando esta for fechada ( Http Code 200 ) , criamos a requisi\u00e7\u00e3o novamente .. e assim por diante ( recursividade )<\/p>\n<pre style=\"font-size:11px;line-height:normal;background-color:#ffffff;\">$ ( document ).ready ( function ( ) {\n       $ ( '#ready' ).on ( 'click' , function ( ) {\n              startPolling = function ( content ) {\n                     content === undefined || $ ( '#response' ).html ( content ) ;\n                     var qs = { 'content' : content } ;\n                     $.get ( 'server.php' , qs , function ( data ) {\n                            startPolling ( data ) ;\n                     } ) ;\n              } ;\n\n              startPolling ( undefined ) ;\n       } ) ;\n} ) ;<\/pre>\n<p style=\"font-family:arial, sans-serif;line-height:normal;background-color:#ffffff;\">S\u00f3 precisamos disso .. bem simples e direto , a unica coisa que tem de demais no c\u00f3digo acima, \u00e9 a recursividade, como eu disse que faz parte da t\u00e9cnica, a conex\u00e3o precisa ser reaberta caso fechada, e ela s\u00f3 \u00e9 fechada quando temos a resposta esperada , para testar basta criar um arquivo html e colocar o seguinte c\u00f3digo<\/p>\n<pre style=\"font-size:11px;line-height:normal;background-color:#ffffff;\">&lt;html&gt;\n       &lt;head&gt;\n              &lt;script type=\"text\/javascript\" src=\"http:\/\/code.jquery.com\/jquery.min.js\"&gt;&lt;\/script&gt;\n              &lt;script type=\"text\/javascript\" src=\"client.js\"&gt;&lt;\/script&gt;\n       &lt;\/head&gt;\n       &lt;body&gt;\n              &lt;input type=\"button\" value=\"ready\" id=\"ready\"&gt;\n              &lt;div id=\"response\"&gt;&lt;\/div&gt;\n       &lt;\/body&gt;\n&lt;\/html&gt;<\/pre>\n<p style=\"font-family:arial, sans-serif;line-height:normal;background-color:#ffffff;\">Isso \u00e9 tudo .. agora fa\u00e7am seus testes, n\u00e3o apliquem uma t\u00e9cnica dessa pra algo que possa ser resolvido de outra forma, estude outras maneiras e principalmente, avaliem o custo benef\u00edcio de cada uma delas, o que foi demonstrado acima funciona, voc\u00ea evita ficar enviando requisi\u00e7\u00f5es ao servidor quando ele est\u00e1 respondendo o que voc\u00ea n\u00e3o quer , me faz lembrar o burro do shrek .<\/p>\n<p style=\"font-family:arial, sans-serif;line-height:normal;background-color:#ffffff;\">Abra\u00e7os, e boa sorte !<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Ol\u00e1 Pessoal ! Como mostrei a forma de se fazer um Long Polling utilizando Node.JS (\u00a0Long Polling com Node.JS\u00a0) , irei mostrar agora a forma de se fazer com PHP. Importante ! Funcionar funciona, apesar de n\u00e3o ser t\u00e3o eficiente quanto ao long polling feito utilizando node.js, n\u00e3o foram testados os efeitos colaterais no servidor, &hellip; <a href=\"https:\/\/leonardocotta.com.br\/?p=867\" class=\"more-link\">Continue reading <span class=\"screen-reader-text\">Long Polling com #PHP<\/span> <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"footnotes":""},"categories":[33,50],"tags":[],"class_list":["post-867","post","type-post","status-publish","format-standard","hentry","category-ajax","category-php"],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/leonardocotta.com.br\/index.php?rest_route=\/wp\/v2\/posts\/867","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/leonardocotta.com.br\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/leonardocotta.com.br\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/leonardocotta.com.br\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/leonardocotta.com.br\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=867"}],"version-history":[{"count":0,"href":"https:\/\/leonardocotta.com.br\/index.php?rest_route=\/wp\/v2\/posts\/867\/revisions"}],"wp:attachment":[{"href":"https:\/\/leonardocotta.com.br\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=867"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/leonardocotta.com.br\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=867"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/leonardocotta.com.br\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=867"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}