Foros del Web » Programando para Internet » Javascript » Frameworks JS »

ejemplo de Comet con PHP: long polling

Estas en el tema de ejemplo de Comet con PHP: long polling en el foro de Frameworks JS en Foros del Web. Hola a todos, hace unos días vi el post de Panino50001 sobre su chatino y me puse a la obra para hacer un ejemplo simple. ...
  #1 (permalink)  
Antiguo 20/03/2009, 06:00
Avatar de ZiTAL  
Fecha de Ingreso: marzo-2004
Ubicación: Bermio (Bizkaia)
Mensajes: 1.545
Antigüedad: 20 años, 1 mes
Puntos: 62
ejemplo de Comet con PHP: long polling

Hola a todos, hace unos días vi el post de Panino50001 sobre su chatino y me puse a la obra para hacer un ejemplo simple. Como bien dice Panino50001 no es un COMET total, ya que desde las misma llamada no puede hacer varias salidas por pantalla, me explico. Yo pensaba que se trataba de hacer una llamada y que esa misma llamada te devolviese los valores cuando hiciese falta, pero la cuestión es que una llamada solo devuelve un resultado, la cuestion es que con este pseudo-comet lo único que sabemos es CUANDO ha cambiado la cosa en el servidor por lo tanto si queremos que el COMET sea continuo, deberemos hacer la llamada a la misma función una y otra vez. Veamos un ejemplo:
- Tengo un fichero: contenido.txt en el cual si el contenido no esta vacío me lo muestre por pantalla:

contenido.txt -> Un fichero vacio

index.php
Código PHP:
<?php
if($_POST)  
{
    
set_time_limit(0); // para quitar el timeout    
    
header("Edge-control: no-store");
    
$content trim(file_get_contents('contenido.txt'));
    while(
$content=='')
        
$content trim(file_get_contents('content.txt'));
    echo 
$content;
    exit();
}
?>
Código HTML:
<html>
<head>	
</head>
<body>
	<div id="content">Cargando...</div>
<script type="text/javascript" src="comet.js"></script>
</body>
</html> 
comet.js
Código javascript:
Ver original
  1. var xmlhttp = function()
  2.     {
  3.         var a;try{a = new XMLHttpRequest();}
  4.         catch(e){try{a = new ActiveXObject('Msxml2.XMLHTTP');}
  5.         catch(e){try{a = new ActiveXObject('Microsoft.XMLHTTP');}
  6.         catch(e){alert('Your browser doesn\'t support ajax');a=false;}
  7.         }}return a;
  8.     }; 
  9.     window.onload = function()
  10.     {
  11.         var a = new comet();
  12.     }; 
  13.     var comet = function()
  14.     {
  15.         var a = new xmlhttp();
  16.         a.open('post',window.location+"?"+Math.random()+"="+Math.random(), true);
  17.         a.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
  18.         a.onreadystatechange = function()
  19.         {
  20.             if(a.readyState == 4)
  21.             {
  22.                 document.getElementById('content').innerHTML = a.responseText;
  23.             }
  24.         };
  25.         a.send('algo=algo');               
  26.     };

y cargamos la página, si tenemos firebug en firefox nos mostrará que la petición ajax está esperando una respuesta.

Ahora abrimos el fichero contenido.txt y escribimos algo.

Veremos como en div 'content' ha cargado lo que hemos guardado en el fichero :)
__________________
http://zital.no-ip.org
____________________

Euskerie ahuen eta bijotzan
  #2 (permalink)  
Antiguo 20/03/2009, 07:55
Avatar de Panino5001
Me alejo de Omelas
 
Fecha de Ingreso: mayo-2004
Ubicación: -34.637167,-58.462984
Mensajes: 5.148
Antigüedad: 19 años, 10 meses
Puntos: 834
Respuesta: ejemplo de Comet con PHP: long polling

Interesante! Qué hace Edge-control? Busqué pero no encontré nada clarificador acerca de su funcionalidad. (Me revaluaste , soy apenas 5001)
  #3 (permalink)  
Antiguo 20/03/2009, 08:30
Avatar de ZiTAL  
Fecha de Ingreso: marzo-2004
Ubicación: Bermio (Bizkaia)
Mensajes: 1.545
Antigüedad: 20 años, 1 mes
Puntos: 62
Respuesta: ejemplo de Comet con PHP: long polling

Es lo que usamos para saltarnos la cache de akamai, creo que no deja guardarlo en cache ;)

Dentro de poco seguimos con este interesante post, ya tengo la segunda parte preparada:

Como seguir con la llamada después de el primer resultado

Gracias por la información Panino5001
__________________
http://zital.no-ip.org
____________________

Euskerie ahuen eta bijotzan
  #4 (permalink)  
Antiguo 24/03/2009, 03:09
Avatar de ZiTAL  
Fecha de Ingreso: marzo-2004
Ubicación: Bermio (Bizkaia)
Mensajes: 1.545
Antigüedad: 20 años, 1 mes
Puntos: 62
Respuesta: ejemplo de Comet con PHP: long polling

Bueno seguimos con esto, ahora haremos que haga recursivamente con retardos de tiempo, porque? Porque sino se bloquearia el navegador, el servidor o los 2 ;):

Código javascript:
Ver original
  1. var xmlhttp = function()
  2.     {
  3.         var a;try{a = new XMLHttpRequest();}
  4.         catch(e){try{a = new ActiveXObject('Msxml2.XMLHTTP');}
  5.         catch(e){try{a = new ActiveXObject('Microsoft.XMLHTTP');}
  6.         catch(e){alert('Your browser doesn\'t support ajax');a=false;}
  7.         }}return a;
  8.     }; 
  9.     window.onload = function()
  10.     {
  11.         var a = new comet();
  12.     }; 
  13.     var comet = function()
  14.     {
  15.         var a = new xmlhttp();
  16.         a.open('post',window.location+"?"+Math.random()+"="+Math.random(), true);
  17.         a.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
  18.         a.onreadystatechange = function()
  19.         {
  20.             if(a.readyState == 4)
  21.             {
  22.                 document.getElementById('content').innerHTML = a.responseText;
  23.                 window.setTimeout(function(){
  24.                     a = new comet();                   
  25.                 },1000);
  26.                
  27.             }
  28.         };
  29.         a.send('algo=algo');               
  30.     };

Solamente con añadir un timeout ya conseguimos ese efecto, en este caso hemos puesto como parametro 1000 ya que el valor hay que ponerlo en milisegundos ;)

Ahora de la parte de PHP:
Código PHP:
<?php
if($_POST)  
{
    
set_time_limit(0);    
    
header("Edge-control: no-store");
    
sleep(1);
    
$content trim(file_get_contents('content.txt'));
    while(
$content=='')
    {
        
sleep(1);
        
$content trim(file_get_contents('content.txt'));
    }
    echo 
$content;
    exit();
}
?>
con sleep conseguimos parar el tiempo en segundos antes de proseguir con la ejecución, también tenemos su equivalente en microsegundos que es el usleep, en nuestro caso:

Código PHP:
<?php
if($_POST)  
{
    
set_time_limit(0);    
    
header("Edge-control: no-store");
    
usleep(1000);
    
$content trim(file_get_contents('content.txt'));
    while(
$content=='')
    {
        
usleep(1000);
        
$content trim(file_get_contents('content.txt'));
    }
    echo 
$content;
    exit();
}
?>
__________________
http://zital.no-ip.org
____________________

Euskerie ahuen eta bijotzan

Última edición por ZiTAL; 24/03/2009 a las 03:36
  #5 (permalink)  
Antiguo 24/03/2009, 10:44
 
Fecha de Ingreso: enero-2009
Mensajes: 455
Antigüedad: 15 años, 2 meses
Puntos: 11
Respuesta: ejemplo de Comet con PHP: long polling

wow, excelente aporte, esperamos ya la tercera parte (si es que la hay)

Cita:
(Me revaluaste , soy apenas 5001)
  #6 (permalink)  
Antiguo 24/03/2009, 14:04
Avatar de ZiTAL  
Fecha de Ingreso: marzo-2004
Ubicación: Bermio (Bizkaia)
Mensajes: 1.545
Antigüedad: 20 años, 1 mes
Puntos: 62
Respuesta: ejemplo de Comet con PHP: long polling

Muchas gracias ;) creo que ya ha quedado claro cual es el concepto del COMET o pseudo-comet o como le querais llamar: Tener una petición abierta hasta que nos llegue el resultado deseado, al contrario de preguntar todo el rato si el resultado deseado ha llegado (modo Homer ;)). A ver si hago un ejemplo más practico que la chorrada que he puesto antes;)
__________________
http://zital.no-ip.org
____________________

Euskerie ahuen eta bijotzan
  #7 (permalink)  
Antiguo 30/03/2009, 16:49
 
Fecha de Ingreso: marzo-2009
Mensajes: 9
Antigüedad: 15 años
Puntos: 0
Respuesta: ejemplo de Comet con PHP: long polling

Zital una pregunta, este ejemplo no es lo mismo que hacer un iframe escondido que este preguntando cada "n" segundos si hay actualización y si encuentra una actualización esta se muestra, o hacerlo con un setInterval() que llame a una funcion y esta muestre algo cuando lo consiga.

Si ese codigo que colocas es lo mismo que lo que yo digo entonces es realmente posible hacer que el cliente se actualice solo cuando el servidor consigue una actualización y este se la envia sin que el cliente este preguntando y preguntado si hay actualizacion.

Saludos
  #8 (permalink)  
Antiguo 30/03/2009, 17:34
Avatar de Panino5001
Me alejo de Omelas
 
Fecha de Ingreso: mayo-2004
Ubicación: -34.637167,-58.462984
Mensajes: 5.148
Antigüedad: 19 años, 10 meses
Puntos: 834
Respuesta: ejemplo de Comet con PHP: long polling

No es lo mismo. Justamente lo que estás describiendo se conoce como polling. Lo descrito arriba es diferente porque no se hacen requests a intervalos regulares al servidor. En lugar de eso lo que se hace es abrir una conexión de larga duración con el servidor, que sólo es interumpida por el servidor (cuando este detecta un cambio de estado) y luego es reiniciada en el cliente cuando se detecta la interrupción de esa conexión. Si probás el código de esta faq y lo mirás en el menú red de firebug, vas a ver que, a diferencia de lo que sucede en el esquema de polling, donde contínuamente hay nuevas entradas, en este esquema sólo hay nuevas entradas cuando hay algún nuevo mensaje para mostrar.
  #9 (permalink)  
Antiguo 31/03/2009, 01:50
Avatar de ZiTAL  
Fecha de Ingreso: marzo-2004
Ubicación: Bermio (Bizkaia)
Mensajes: 1.545
Antigüedad: 20 años, 1 mes
Puntos: 62
Respuesta: ejemplo de Comet con PHP: long polling

creo que Panino5001 te ha respondido mejor de lo que hubiese hecho yo ;)
__________________
http://zital.no-ip.org
____________________

Euskerie ahuen eta bijotzan
  #10 (permalink)  
Antiguo 22/05/2009, 11:07
 
Fecha de Ingreso: marzo-2009
Mensajes: 9
Antigüedad: 15 años
Puntos: 0
Respuesta: ejemplo de Comet con PHP: long polling

Ok, ahora otra inquietud, este esjemplo es con un txt pero como seria implementar este codigo con una BD, es decir, al cambiar x valor en una tabla en una BD.

Pregunto esto porque veo que el cuando se abre la conexion de larga duración en el servidor este va a consultar "n" veces la BD para ver si ocurrio algun cambio. Entonces estaremos bombardenado el servidor y la BD con consultas.

¿Esto sería la manera adecuada de hacerlo o lo estoy viendo equivocadamente?

Saludos
  #11 (permalink)  
Antiguo 22/05/2009, 11:15
Avatar de ZiTAL  
Fecha de Ingreso: marzo-2004
Ubicación: Bermio (Bizkaia)
Mensajes: 1.545
Antigüedad: 20 años, 1 mes
Puntos: 62
Respuesta: ejemplo de Comet con PHP: long polling

El truco está en el:
Código PHP:
sleep 
que hace un parón de x segundos para que lo vuelva a intentar. Por lo tanto ese bombardeo lo configuras tú.

La cuestión es que tipo de aplicación quieres hacer, por ejemplo si quieres hacer un chat, creo que es el modo apropiado.
__________________
http://zital.no-ip.org
____________________

Euskerie ahuen eta bijotzan
  #12 (permalink)  
Antiguo 05/09/2009, 19:10
 
Fecha de Ingreso: septiembre-2009
Mensajes: 7
Antigüedad: 14 años, 7 meses
Puntos: 0
Respuesta: ejemplo de Comet con PHP: long polling

Hola Necesito Saber Si Ajuro tengo Que Usar Prototype, O Puedo Usar Simplemente Ajax, Me Refiero Al Ajax Normal, Sin la Clase Prototype! Gracias!
  #13 (permalink)  
Antiguo 06/09/2009, 02:05
Avatar de ZiTAL  
Fecha de Ingreso: marzo-2004
Ubicación: Bermio (Bizkaia)
Mensajes: 1.545
Antigüedad: 20 años, 1 mes
Puntos: 62
Respuesta: ejemplo de Comet con PHP: long polling

aquí no se usa prototype, se usa ajax normal
__________________
http://zital.no-ip.org
____________________

Euskerie ahuen eta bijotzan
  #14 (permalink)  
Antiguo 07/09/2009, 21:08
 
Fecha de Ingreso: septiembre-2009
Mensajes: 7
Antigüedad: 14 años, 7 meses
Puntos: 0
Respuesta: ejemplo de Comet con PHP: long polling

Hola, Tengo Una Duda Como Haria! Para! Que Los Datos Del Chat No se Pierdan al Recargar O a darle Sig o atras a la Pagina!, Asi Como facebook, Con Un Iframe!?..Me Refiero a Q No Se Pierdan Las Ventanas De Las Personas Con Q Se Esta ChateandO..Espero Q Me Puedan Aclarar Esa Duda!, Pense Q Con Sesiones!, Bueno Espero Q Me Puedan ayudar y Darme Un Ejemplo!

Última edición por chevito; 23/09/2009 a las 12:23
  #15 (permalink)  
Antiguo 09/10/2010, 21:32
 
Fecha de Ingreso: octubre-2010
Mensajes: 1
Antigüedad: 13 años, 6 meses
Puntos: 0
Pregunta Respuesta: ejemplo de Comet con PHP: long polling

Me gustaria tener una idea de como implementa Comet pero no la variante long polling sino la streaming, si pueden ayudenme con eso
  #16 (permalink)  
Antiguo 18/04/2011, 01:56
 
Fecha de Ingreso: abril-2011
Mensajes: 1
Antigüedad: 13 años
Puntos: 0
Respuesta: ejemplo de Comet con PHP: long polling

Chicos, lo siento pero no veo que este ejemplo funcione correctamente. Lo he probado en mi servidor, y en lugar de dejar una peticion viva, hace peticiones que mueren, como un pooling normal......

Podriais confirmarme que el ejemplo esta mal? O he hecho algo mal yo???

Un saludo
  #17 (permalink)  
Antiguo 26/03/2012, 11:51
 
Fecha de Ingreso: enero-2012
Ubicación: en buenos aires
Mensajes: 41
Antigüedad: 12 años, 2 meses
Puntos: 1
Respuesta: ejemplo de Comet con PHP: long polling

tengo una duda, como puedo hacer que cuando se envié o se recibe un mensaje la barra de desplazamiento baje al mensaje recibido

intente lo siguiente

Código Javascript:
Ver original
  1. document.getElementById('content').scrollTop = document.getElementById('content').scrollHeight;

pero el problema que tengo es que esta continuamente bajando y no deja ver todo el resto de la conversación

agradezco alguna ayuda.
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta

SíEste tema le ha gustado a 7 personas




La zona horaria es GMT -6. Ahora son las 07:25.