webchat en tiempo real con php y mysql

Después de un pequeño descanso volvemos a las andadas. Esta vez voy a mostrar como crear un webchat en tiempo real.

El problema de los webchat es que la inmensa mayoría de los que existen se dedican a refrescar la página de la charla cada X tiempo o cuando el usuario ha escrito un mensaje. Esto es debido a que el protocolo HTTP esta diseñado para que una vez recibido los datos cierre la conexión, y si queremos recuperar datos nuevos tenemos que hacer una nueva petición.

Para lograr una interactividad y un realismo temporal cercanos al irc, messenger, etc. y seguir usando la web tenemos que usar un truco, y es crear una página que nunca termine de ejecutarse. Quizá os pregunteis que si nunca termina de ejecutarse, entónces no saldrá ningún resultado, pues bién, podemos desactivar el buffer del php desde el principio o hacer un volcado continuo para que cada dato nuevo se vaya enviando al navegador del cliente. Los navegadores muestran el contenido según les va llegando, por lo que una sentencia como esta (en pseudocodigo):

mientras verdadero
recupera mensajes nuevos
muestra mensajes nuevos
fin del mientras

haría que cada vez que un mensaje nuevo apareciese se enviase al navegador y este lo mostrara instantaneamente, con lo que habríamos conseguido que fuese el tiempo real.

Parar lograr este planteamiento en php tenemos que seguir los siguientes pasos (he reducido su código para simplificarlo):

ob_start();

Que activa el tratamiento del buffer en php

set_time_limit(0);

Indica al motor de php que el script nunca debe caducar a pesar de lo que dure.


for(;;)
{

Este es el bucle que constantemente se va repitiendo.


$rs=mysql_query(«SELECT * FROM chat_mensajes WHERE IDMensaje>'» . $id . «‘ AND WEEK(DatFecha,1)=WEEK(NOW(),1) AND YEAR(DatFecha)=YEAR(NOW()) ORDER BY IDMensaje»)
or die («No se puede realizar la consulta»);

En mi caso guardo los mensajes en una base de datos mysql, por lo que con la consulta SQL compruebo aquellos mensajes cuyo ID sea mayor que el último ID de mensaje que se ha mostrado (solo aquellos dentro de la semana actual del año en curso).


if(mysql_num_rows($rs)>0)
{
while($fila=mysql_fetch_array($rs,MYSQL_ASSOC)) {

Compruebo si hay nuevos mensajes y los recorro.


$id=$fila[«IDMensaje»];

Voy actualizando la variable id para que contenga al final el último ID y así en la siguiente pasada del bucle solo recoger los últimos mensajes escritos a partir del indicado.


echo «<div>\n»;
echo «<span>» . $fila[«DatFecha»] . » » . «</span>»;
echo «<span>» . $fila[«StrUsuario»] . «&gt;</span>»;
echo «<span>» . $fila[«StrMensaje»] . «</span>»;
echo «</div>\n»;
}

Se va mostrando el contenido de los mensajes (fecha, remitente y mensaje).


echo «<script>scrollTo(0,999999999);</script>\n»;
ob_flush();
flush();
}

Con un pequeño truco en javascript logramos desplazar la ventana del navegador siempre hasta el final del contenido. A continuacuón vaciamos el buffer hacia el navegador del cliente.


sleep(1);
}

Para no recargar mucho el servidor mysql haciendo constantemente consultas, pausamos durante un segundo la ejecución para después continuar con la siguiente iteración del bucle.

Quizá penseis que esta solución recarga mucho el servidor (tanto el web como el de mysql), pero el impacto es mínimo y si teneis un hosting esto os ahorrará ancho de banda puesto que gasta más por usuario el estar haciendo peticiones al servidor web cada X tiempo que una sola petición que dure eternamente (solo gasta lo que envia, como una petición normal); en cuanto al servidor mysql si este esta en localhost (como el 99% de los hosting) el impacto es mínimo porque no consume ningún recurso de red, además de que el propio mysql es rapídisimo y eficiente haciendo las consultas y no mermará el rendimiento por estar haciendo una cada segundo por cada usuario. Sin embargo si no quereis usar mysql, podeis usar ficheros (fopen) o bién memoria compartida (Shmop). Por supuesto esto no es la panacea, pero para cosas pequeñas (20 personas a la vez) si puede ir bién tenerlo así montado.

En la web en la que colaboro tengo implementado este sistema, que aunque lo tengo bastante desarollado, todavía tengo que mejorar ciertos aspectos de funcionalidad.

19 comentarios en “webchat en tiempo real con php y mysql

  1. Anonymous

    Hola, he estado mirando tu articulo sobre webchat en PHP y querria preguntar si sabes si alguien sabe si la programacion en visual c variaria mucho o se parece a la que se ha comentado.

    La cuestion es que queremos hacer algo parecido , es decir, ofrecer un chat y lo vamos a intentar en visual c.

    Gracias de todos modos

    Responder
  2. sistemasorp

    No entiendo muy bién lo que quereis hacer:

    ¿un webchat con visual c++ (añgo parecido a un servicio web)?

    ¿un chat con visual c++ que tire de una base de datos?

    ¿un chat en visual c++ que use sockets tcp/ip.?

    Responder
  3. Anonymous

    hola de nuevo:

    Bueno aver si me consigo explicar…Soy un estudiante de telecomunicaciones y este curso tenemos que hacer el trabajo de fin de carrera(Tecnica de teleco) y tenemos pensado desarrollar un software para PDAs que incluya una serie de servicios: VoIP, servicio de mensajeria(mails) y tambien un servicio de chat. Para ellos vamos a utilizar Visual c porque nos han comentado que es el lenguaje apropiado para estos dispositivos.
    Y mi pregunta, viene mas relacionada acon el servicio de chat.Teniamos la idea de hacer un servidor alojado en un ordenador y que estuviera corriendo todo el rato,funcionando, y asi, por ejemplo los usuarios que dispongan de nuestro futuro sofware puedan conectarse a el y hablar en una conversacion conjunta a modo de chat. Tambien querriamos dar la posibilidad de hablar de forma privada. Para todo esto estamos mirando mil cosas para poner en la documentacion del proyecto ya que aun solo tenemos que hacer el anteproyecto y no meternos de lleno con la programacion.

    Si tienes alguna sugerencia u orientacion comentame.

    gracias

    Responder
  4. sistemasorp

    En embedded visual c++ o visual c# o embedded visual basic o visual basic .net.

    Mi recomendación es usar sockets para conectaros al servidor. Si quereis que salga lo que se ha escrito previamente el programa en el servidor debería hacer una consulta en una base de datos la primera vez que se conecta un usuario y luego guardar todo lo que se escribe en esa base de datos. La gestión de conversaciones públicas o privadas yo lo implementaría con el estandar jabber.

    Espero que con esto te sriva.

    Responder
  5. Anonymous

    A mi me ha parecido una solución muy buena la del webchat.
    Yo tengo un proyecto en marcha en el que hay un webchat que se recarga cada vez que el usuario hace una acción (a parte de hablar).
    Así que este artículo me va a venir pero que muy bien 😀
    Es justo lo que andaba buscando.
    No creo que sea en absoluto una chapuza. Simplemente se aprovechan las «peculiaridades» que ofrece PHP.
    Muy bueno.
    Saludos.

    Responder
  6. Anonymous

    a bueno no, lo he leido entero.. es una chapu , creia k podrias manegar conexiones en paralelo.
    yo estoy haciendo un cliente jabber y el problema es que puedo tener conexiones pero … necesito mas de una para poder traer la lista de usus conectados mientras tienes otra conexion abierta para charlar con otro… un problema si

    Responder
  7. Anonymous

    tio has usado tu chat?va un «poco» chungo yo lo volveria a revisar todo un poco,chatea con un pc ke tengas a la vista,yo no dejaria este foro colgado

    Responder
  8. sistemasorp

    Hola Arturo.

    ¿Puedes ser un poco más explicito? ¿Que parte necesitas?, ya que el chat en cuestión que muestro esta especializado para la página de star wars y para adaptarlo a otro habría que hacer muchos cambios. Por eso es mejor empezar de 0 y preguntarme las dudas. Un saludo.

    Responder
  9. arturo

    bien gracias por responder, pues mire estoy programando un chat y para el necesito un ejemplo. yo estudio informatica y se programar en php algunas cosillas. y si me envian la carpeta con todo los codigos yo lo analizaria. si existe condicion por favor haganmela saber ya saben mi correo cuando.puedas@hotmail.com me gustaria el suyo para conversar en tiempo real.y poder ser mas explicito. gracias

    Responder
  10. Ralph Moran

    Saludos.

    Busco conexiones en tiempo real, verdadero tiempo real, algo asi como el juego de Ragnarok donde los eventos de otro usuario los pueden ver los demas.

    Ejemplo:

    Yo como usuario muevo mi avatar a la derecha de la pantalla, se manda este evento al servidor por socket, un cron (demonio o script) esta a la escucha del puerto, recibe un xml, lo analiza para saber que sala, usuario y evento, se hace replica a todos los demas usuarios relacionados.

    Tengo idea de hacerlo con Java el script que manipule los puertos, solo en teoria, por que no se programarlo.

    Alguien que ayude a un camarada en aprietos con:

    1.- Como administrar sockets
    2.- Como parsear XMLs
    3.- Con que gestor de Java me recomiendan, solo tengo Eclipse
    4.- Como levantar el servicio Java que he realizado en el servidor para que comienze a trabajar (escuchar puertos)

    Espero haber sido claro.

    Un saludo enorme y gracias por todo.

    Ralph Moran

    Responder
  11. Anonymous

    Una pedazo de carga al servidor que no hay dios que la soporte. Ahora prueba tu chat con 20 usuarios…. por no decirte con 100

    Responder
  12. sistemasorp

    Como decía en el artículo 20 personas ha ido sin problemas en un servidor de hosting por internet. Más personas ya no resulta recomendable.

    Responder
  13. Recio

    hola, me preguntaba si te importaria decirme como haces para no cargarte el servicio mysql con 20 usuarios hablando, como borras mensajes para no consumir el espacio poco a poco, ademas, yo tb necesito hacer un chat, con usuarios ya registrados en una base de datos , y me gustaria que me dieras tu codigo, como guia, no es mi intencion copiarlo, pero no me siento capaz sin un tutor, y seria un placer que ese tutor fueras tu; mi correo es : luisjgrecio@gmail.com

    Responder
  14. Pingback: Pachamama » Blog Archive » ¿Te han bloqueado el acceso al chat o deseas que no te pillen en tu trabajo?

Responder a sistemasorp Cancelar la respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *