Cómo hacer un aviso en tiempo real “El usuario está escribiendo” a todos en el chat

Quiero escribir una aplicación de chat, usando jQuery y PHP. La parte en la que necesito ayuda es donde un usuario en tiempo real “Evx” está escribiendo un mensaje y luego muestra ese mensaje a todos los demás usuarios en tiempo real. Esto sería similar a cómo Skype tiene un lápiz … y cómo Facebook tiene un aviso cuando el usuario escribe.

Lo que necesito es algo de ayuda con los pasos lógicos y la información sobre cómo lograr fácilmente el tiempo real “que el usuario está escribiendo”, pero que funcione igual de bien que de ninguna otra manera.

Esto es lo que he intentado hasta ahora:

//time delay before ajax call var delay = (function() { var timer = 0; return function(callback, ms) { clearTimeout(timer); timer = setTimeout(callback, ms); }; })(); $('#usermsg').keydown(function() { if ($('#usermsg').val().length === 5) { delay(function() { $.ajax({ url: "addusertyping.php", cache: false, success: function() { } }); }, 5000); } }); $('#usermsg').keyup(function() { if ($('#usermsg').val().length >= 6) { // here I should basically check for // an update from server or what not. } });​ 

¿Puede alguien explicar los pasos e información sobre cómo lograr que los usuarios digiten en tiempo real, utilizando lo que he probado anteriormente como punto de partida?

El enfoque que los sitios como Facebook y Google Talk usan al implementar el chat es usar soluciones que aprovechan el modelo de solicitud / respuesta de la Web usando Comet o Reverse AJAX.

Web 1.0:

En las implementaciones tradicionales de Web 1.0, como la suya, el navegador inicia una solicitud al servidor. El servidor responde con datos que el código del lado del cliente representa en la vista.

Esto funciona muy bien cuando simplemente estamos moviendo usuarios de una página a otra o cuando estamos respondiendo a eventos iniciados por el usuario. Sin embargo, esta metodología es intrínsecamente defectuosa cuando se trata de administrar eventos iniciados por el servidor.

En su ejemplo, para simular actualizaciones en tiempo real, debe analizar el servidor con solicitudes de sondeo continuas para buscar actualizaciones. Esto es el equivalente del niño pequeño en el asiento trasero del automóvil que constantemente y constantemente le pregunta a su padre “¿Ya llegamos? ¿Ya llegamos?” una y otra vez sin falta. Esto no solo consume mucho ancho de banda sino que crea una gran carga en el servidor cuando aumenta el número de clientes conectados.

Comet / Reverse AJAX:

Como el servidor no puede iniciar respuestas al navegador sin una solicitud, se usa una técnica llamada “AJAX inverso” o “Cometa” para simular el proceso del servidor que envía notificaciones de eventos al cliente.

La premisa general detrás de Comet es que el navegador abre una conexión con el servidor y luego el servidor mantiene esa conexión abierta indefinidamente. Cuando el servidor tiene una actualización que debe pasar a todos los clientes conectados, luego envía la respuesta de vuelta al cliente, completando el ciclo de solicitud / respuesta. Al recibir la respuesta, los clientes inmediatamente envían otra solicitud al servidor, que el servidor una vez más permanece abierta hasta la próxima actualización.

Hay soluciones Comet disponibles para PHP, por lo que esto es algo que podría lograr usando su plataforma existente; Sin embargo, no puedo recomendar ninguno. También necesitará una biblioteca del lado del cliente para facilitar la apertura de las conexiones de Comet. Consulte la Biblioteca JavaScript de Dojo Cometd .

Comet es una de las dos soluciones superiores para implementar una solución de chat, y la otra es WebSockets. Sin embargo, todavía falta soporte para WebSockets en algunos navegadores.

Al buscar una biblioteca que facilite Comet, también es una buena idea seleccionar una que facilite Continuations, que ayuda a garantizar que los hilos que están esperando enviar una respuesta se puedan liberar para realizar otras tareas en lugar de esperar sin hacer nada. ¡Con esta solución, algunos servidores Comet han escalado fácilmente a más de 20,000 conexiones!

Aquí hay un artículo que describe Cómo implementar Comet en PHP . Además, puede encontrar esta pregunta de StackOverflow útil ya que describe los desafíos de usar Comet en PHP .

Consideraciones de diseño:

Uno de los primeros errores que cometimos al desarrollar nuestra solución de chat fue no pensar en los mensajes como una subclase de algo más abstracto. En cambio, la información que enviamos del servidor al frontend fue simplemente un “mensaje de chat”. Sin embargo, a medida que avanzaba el producto, pronto descubrimos que la misma conexión de Comet podía utilizarse para enviar comandos al navegador, no solo mensajes.

Por lo tanto, para implementar su “Usuario está escribiendo”, es posible que necesite un controlador en su JavaScript que primero determine si la actualización del servidor es un mensaje nuevo, o es el comando “Mostrar que el usuario XYX está escribiendo”. Un buen diseño también puede garantizar que pueda usar la conexión de Comet para otros tipos de actualizaciones que iniciarían desde el servidor.

Por último, su mensaje de mecanografía debe tener algún tipo de retraso, de modo que cuando un usuario escriba, su navegador solo notificará al servidor una vez cada X segundos. Si vincula a su usuario a un evento de pulsación de tecla que simplemente golpea al servidor con solicitudes de AJAX, entonces simplemente está degradando su conexión de Comet nuevamente en el sondeo.

En el extremo del destinatario, lo más probable es que desee implementar una función de tiempo de espera para que el mensaje de Mecanografía del usuario desaparezca automáticamente si el usuario que está escribiendo deja de enviar solicitudes de “mecanografía por el usuario” al servidor. Alternativamente, el navegador de ese usuario podría enviar un mensaje de “El usuario no escribe más” si el navegador envía una solicitud cuando su cuadro de texto está vacío, como cuando el usuario retrocede el texto ingresado.

¿Soluciones fáciles ?:

Finalmente, quiero agregar que esto implicará una curva de aprendizaje, ya que debes pensar en la Web desde la perspectiva del servidor que envía datos al cliente. Esto requerirá mucha investigación y dedicación de su parte, además de probar ejemplos y obtener una comprensión muy sólida de cómo debe abordar el diseño de su aplicación. Esta es, con mucho, una de las mejores formas de dominar esta técnica, pero también puede ser intimidante. Solo asegúrese de tomarse su tiempo con los ejemplos, pruébelos usted mismo, y si se queda atascado, siempre puede pedir ayuda.