Comet es una tcnica de programacin que permite a los servidores web enviar datos al cliente sin ninguna necesidad de que ste lo solicite. En aplicaciones AJAX ocurre lo contrario, el cliente (el navegador web) no puede ser notificado en tiempo real por el servidor si se han producido cambios en ste. Es el usuario quien deber realizar la peticin, quizs haciendo clic en un vinculo, botn mediante una solicitud peridica a fin de obtener datos del servidor. En est oportunidad vamos aplicar Comet con PHP y Prototype. Nos basaremos en un iframe oculto. El objetivo es que el cliente no pida al servidor, sino que el servidor envie datos al cliente.
El archivo backend.php
cliente est conectado.
El script backend.php, har un bucle infinito y devolver la hora UNIX siempre y cuando el
<?php header("Cache-Control: no-cache, must-revalidate"); header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); flush(); //flush -> vacia el bfer de salida de PHP y ademas envia todo lo escrito (echo, print, ect) al navegador del cliente ?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>Comet php backend</title> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> </head> <body> <script type="text/javascript"> //Navegadores KHTML no compartes javascripts entre iframes var is_khtml = navigator.appName.match("Konqueror") || navigator.appVersion.match("KHTML"); if (is_khtml) {
var prototypejs = document.createElement('script'); prototypejs.setAttribute('type','text/javascript'); prototypejs.setAttribute('src','prototype.js'); var head = document.getElementsByTagName('head'); head[0].appendChild(prototypejs); } // cargamos objeto comet (esto en realidad es el nombre del iframe) var comet = window.parent.comet; </script> <?php while(1) { // while (1) permite un bucle infinito echo '<script type="text/javascript">'; echo 'comet.printServerTime('.time().');'; echo '</script>'; flush(); sleep(1); // un descanso para aliviar el CPU del servidor } ?> </body> </html>
El archivo index.html
Este documento HTML cargar la librera Prototype dentro de las etiquetas <head>, tambin creamos dentro de <body> un contenedor donde se mostrar el resultado de la peticin al servidor, sea la hora UNIX: <div id="content"> </div>, y finalmente se crear el objeto Comet que se conectar a nuestro archivo PHP. El objeto Coment crea etiquetas <iframe> invisibles (esto quizs varie en algunos navegadores). Estos iframes se encargarn de crear el "terreno" (por as decirlo) para la conexin HTTP persistente al archivo/script PHP.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>Comet demo</title> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <script type="text/javascript" src="prototype.js"></script> </head> <body> <div id="content">La hora del servidor se mostrar aqui</div> <script type="text/javascript"> var comet = { connection : false, iframediv : false, initialize: function() { if (navigator.appVersion.indexOf("MSIE") != -1) { // Para navegadores IE
comet.connection = new ActiveXObject("htmlfile"); comet.connection.open(); comet.connection.write("<html>"); comet.connection.write("<script>document.domain = '"+document.domain+"'"); comet.connection.write("</html>"); comet.connection.close(); comet.iframediv = comet.connection.createElement("div"); comet.connection.appendChild(comet.iframediv); comet.connection.parentWindow.comet = comet; comet.iframediv.innerHTML = "<iframe id='comet_iframe' src='./backend.php'></iframe>"; } else if (navigator.appVersion.indexOf("KHTML") != -1) { // Para navegadores KHTML comet.connection = document.createElement('iframe'); comet.connection.setAttribute('id', 'comet_iframe'); comet.connection.setAttribute('src', './backend.php'); with (comet.connection.style) { position = "absolute"; left = top = "-100px"; height = width = "1px"; visibility = "hidden"; } document.body.appendChild(comet.connection); } else { // Para otros navegadores (Firefox...) comet.connection = document.createElement('iframe'); comet.connection.setAttribute('id', 'comet_iframe'); with (comet.connection.style) { left = top = "-100px"; height = width = "1px"; visibility = "hidden"; display = 'none'; } comet.iframediv = document.createElement('iframe'); comet.iframediv.setAttribute('src', './backend.php'); comet.connection.appendChild(comet.iframediv); document.body.appendChild(comet.connection); } }, // esta funcin ser llamada desde backend.php printServerTime: function (time) { $('content').innerHTML = time; }, onUnload: function() { if (comet.connection) { comet.connection = false; // se eliminar el iframe para prevenir problemas con IE cuando se recargue la pagina. } } }