Ver Mensaje Individual
  #1 (permalink)  
Antiguo 16/08/2010, 11:28
Avatar de Kenichi
Kenichi
 
Fecha de Ingreso: enero-2009
Ubicación: Rosario, Argentina
Mensajes: 160
Antigüedad: 15 años, 11 meses
Puntos: 6
[APORTE] Como hacer tiempo real con AJAX

Buenas, hace tiempo estaba buscando una forma de hacer aplicaciones en tiempo real con PHP y JavaScript. Intenté usar AJAX pero la única forma era actualizar cada X segundos.
Y al fin logré hacer tiempo real, esta es la idea de como hacerlo:
  • Mantener actualizada una conexion AJAX buscando un archivo en el servidor
  • Si el archivo existe, actualizo la aplicación
  • Si la el archivo no existe, la aplicación no ha sufrido cambios y no actualizo
Y parece que lo anterior funciona perfecto :D
Aca les dejo los archivos:

servidor.html (el archivo que recibe los mensajes)
Código HTML:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
  <meta http-equiv="content-type" content="text/html; charset=windows-1250">
  <script type="text/javascript" src="funciones.js"></script>
  <title>Tiempo real AJAX</title>
  </head>
  <body></body>
</html> 
funciones.js (la magia :P)
Código Javascript:
Ver original
  1. // ################################## AJAX ########################################
  2.   function crearAJAX()
  3.   {
  4.    try
  5.    {
  6.     var AJAX = new ActiveXObject("Microsoft.XMLHTTP");
  7.    }
  8.    catch (e)
  9.    {
  10.     try
  11.     {
  12.      var AJAX = new XMLHttpRequest();
  13.     }
  14.     catch (e)
  15.     {
  16.      alert("El navegador que estas usando no soporta AJAX.\nPor favor, descarga uno mas moderno");
  17.      return false;
  18.     }
  19.    }
  20.    return AJAX;
  21.   }    
  22.   // ########################## Tiempo Real (magia) ##################################
  23.   var ajax;
  24.   var actualizaciones = 0;
  25.   function mantener_actualizado()
  26.   {
  27.    // Crear una conexion nueva
  28.    ajax = crearAJAX();
  29.    // Procesar los cambios de estado
  30.    ajax.onreadystatechange = function()
  31.    {
  32.     if (ajax.readyState == 4)
  33.     {
  34.      // Aca esta la magia de nuevo
  35.      if (ajax.status == 200)
  36.      {
  37.       // Si el archivo existe procesamos los cambios
  38.       hay_cambios(ajax.responseText);
  39.      }
  40.      else
  41.      {
  42.       // Sino esperamos 300 milisegundos y actualizamos nuevamente
  43.       setTimeout("mantener_actualizado()", 300);
  44.      }
  45.     }
  46.    }
  47.    ajax.open('GET','ajax/sin_cambios.txt', true);
  48.    ajax.send(null);
  49.   }
  50.   window.onload = function()
  51.   {
  52.    // Crear al AJAX
  53.    ajax = crearAJAX();
  54.    // Procesar los cambios en la conexion
  55.    ajax.onreadystatechange = function()
  56.    {
  57.     if (ajax.readyState == 4)
  58.     {
  59.      // Aca esta la magia
  60.      if (ajax.status == 200)
  61.      {
  62.       // Si el archivo existe significa que hay cambios
  63.       // Obtenemos los cambios con responseText
  64.       hay_cambios(ajax.responseText);
  65.      }
  66.      else
  67.      {
  68.       // Si todavia no hay cambios esperamos un momento y actualizamos
  69.       // Si o si hay que esperar al menos 300 milisegundos, no se por que
  70.       setTimeout("mantener_actualizado()", 300);
  71.      }
  72.     }
  73.    }
  74.    // Abrimos el archivo que nos dira si hay cambios o no
  75.    ajax.open('GET','ajax/sin_cambios.txt', true);
  76.    ajax.send(null);
  77.    // y... volvemos
  78.    return;
  79.   }
  80.   function hay_cambios(texto)
  81.   {
  82.    // Creamos una conexion nueva
  83.    ajax = crearAJAX();
  84.    // Hay que cambiar la direccion que se carga
  85.    // para avisar que ya sabemos que hubo cambios
  86.    ajax.onreadystatechange = function()
  87.    {
  88.     if (ajax.readyState == 4 && ajax.status == 200)
  89.     {
  90.      // Cuando ya se borro el archivo ajax/sin_cambios.txt volvemos a actualizar
  91.      setTimeout("mantener_actualizado()", 300);
  92.     }
  93.    }
  94.    // Aca abrimos una URL diferente
  95.    // Este archivo que abrimos borra el ajax/sin_cambios.txt para "avisar" que ya mostramos los cambios
  96.    ajax.open('GET','actualizado.php', true);
  97.    ajax.send(null);
  98.    // No pasa nada despues se va a ejecutar mantener_actualizado()
  99.    // y volvera a verificar cambios ;)
  100.    // Modificamos el titulo y el contenido de la pagina
  101.    document.title = 'Tiempo real AJAX (1)';
  102.    document.body.innerHTML = texto;
  103.    // Despues de 3 segundos vuelve a cambiar el titulo por el inicial
  104.    setTimeout(function(){
  105.     document.title = 'Tiempo real AJAX';
  106.    }, 3000);
  107.    // ...y eso es todo
  108.    return;
  109.   }

cliente.php (el archivo que envia los mensajes)
Código PHP:
Estas listo para la magia? Escribi un mensaje y pone enviar :P<br>
<form action="" method="post">
 <textarea style="width:300px;height:150px;padding:3px;" name="mensaje"></textarea><br>
 <input type="submit" value="Enviar">
</form>
<?php
if (isset($_POST['mensaje']))
{
 
// Recibimos el mensaje
 
$mensaje htmlentities($_POST['mensaje'], ENT_QUOTES);
 echo 
'<hr>';
 
// Y despues intentamos crear el archivo
 
$fp fopen('ajax/sin_cambios.txt','a');
 
fputs($fp$mensaje);
 
fclose($fp);
 
// Le damos permisos chmod 777 para que luego se pueda borrar
 
@chmod('ajax/sin_cambios.txt'0777);
 
// Avisamos que enviamos el mensaje
 
echo "Mensaje enviado.";
 
// Facil no?
}
?>
actualizado.php (borra los cambios luego de mostrarlos)
Código PHP:
<?php
// Si el archivo existe lo borra
// Esto es porque ya sabemos que hubo cambios
@unlink('ajax/sin_cambios.txt');
?>
Como ven traté de comentar todo para que puedan entenderlo lo mejor posible.
Pueden ver una demo aqui:
El cliente: http://linkenforos.com.ar/lab/tiempo_real/cliente.php
Servidor: http://linkenforos.com.ar/lab/tiempo_real/servidor.html
Para que puedan verlo bien deben abrir las dos cosas y enviar un mensaje desde el cliente.php, la otra pagina automáticamente lo mostrará

Bugs conocidos:
- Si se esta ejecutando en un servidor NO local, no se pueden enviar varios mensajes
- Debe tomarse al menos 300 milisegundos de espera antes de actualizar los datos, no se por que

Espero que este aporte sea útil.
Saludos.
__________________
Cansado de tener que hacer webs con doble login, o no entender nada del codigo de phpBB? Usa un sistema de foros simple, usa Linken Foros