php - plugin - Preguntas generales sobre el sondeo largo/transmisión HTTP
wordpress add meta keywords (2)
Estoy tratando de hacer una aplicación de chat web teórica con php y jquery , he leído sobre encuestas largas y http streaming, y logré aplicar la mayoría de los principios introducidos en los artículos. Sin embargo, hay dos cosas principales que todavía no puedo entender.
Con larga encuesta
- ¿Cómo sabrá el servidor cuando se haya enviado una actualización? ¿Necesitará consultar la base de datos continuamente o hay una mejor manera?
Con HTTP Streaming
- ¿Cómo verifico los resultados durante la conexión Ajax que todavía está activa? Soy consciente de la función de
success
de jQuery para llamadas ajax, pero ¿cómo verifico los datos mientras la conexión aún está en curso?
Apreciaré cualquiera y todas las respuestas, gracias de antemano.
¿Cómo verifico los resultados durante la conexión Ajax que todavía está activa? Soy consciente de la función de éxito de jQuery para llamadas ajax, pero ¿cómo verifico los datos mientras la conexión aún está en curso?
En realidad, usted puede. He proporcionado una respuesta revisada para lo anterior, pero no sé si aún está pendiente o si se ha ignorado. Proporcionar una actualización aquí para que la información correcta esté disponible.
Si mantiene abierta la conexión entre el cliente y el servidor, es posible enviar actualizaciones a través de las cuales se adjuntan a la respuesta. A medida que cada actualización viene en el evento XMLHttpRequest.onreadystatechange
se activa y el valor de XMLHttpRequest.readyState
será 3. Esto significa que el XMLHttpRequest.responseText continúa creciendo.
Puede ver un ejemplo de esto aquí: http://www.leggetter.co.uk//7213549/
Para ver el código JS simplemente vea la fuente. El código PHP es:
<?php
$updates = $_GET[''updates''];
if(!$updates) {
$updates = 100;
}
header(''Content-type: text/plain'');
echo str_pad(''PADDING'', 2048, ''|PADDING''); // initial buffer required
$sleep_time = 1;
$count = 0;
$update_suffix = ''Just keep streaming, streaming, streaming. Just keep streaming.'';
while($count < 100) {
$message = $count . '' >> '' . $update_suffix;
echo($message);
flush();
$count = $count + 1;
sleep($sleep_time);
}
?>
En los navegadores basados en Gecko, como Firefox, es posible reemplazar completamente el texto de responseText
utilizando multipart/x-mixed-replace
. No he dado un ejemplo de esto.
No parece que sea posible lograr el mismo tipo de funcionalidad utilizando jQuery.ajax
. La devolución de llamada success
no se onreadystatechange
cuando se onreadystatechange
evento onreadystatechange
. Esto es sorprendente ya que la documentación dice:
Sin embargo, no se proporciona un mecanismo de cambio onreadystatecange, ya que el éxito, error, completo y statusCode cubren todos los requisitos posibles.
Entonces, ¿la documentación es potencialmente incorrecta a menos que la malinterprete?
Puede ver un ejemplo que intenta utilizar jQuery aquí: http://www.leggetter.co.uk//7213549/jquery.html
Si echas un vistazo a la pestaña de red en las herramientas Firebug o Chrome Developer verás que el tamaño del archivo de stream.php
creciendo, pero la devolución de llamada success
aún no está activada.
Sí, las técnicas similares a las de los cometas usualmente hacen explotar el cerebro al principio, solo haciéndote pensar de una manera diferente. Y otro problema es que no hay muchos recursos disponibles para PHP, porque todos están haciendo su Comet en node.js, Python, Java, etc.
Intentaré responder a sus preguntas, espero que arroje algo de luz sobre este tema para las personas.
¿Cómo sabrá el servidor cuando se haya enviado una actualización? ¿Necesitará consultar la base de datos continuamente o hay una mejor manera?
La respuesta es: en el caso más general, debe usar una cola de mensajes (MQ). RabbitMQ o la funcionalidad Pub / Sub incorporada en la tienda Redis pueden ser una buena opción, aunque hay muchas soluciones competitivas disponibles en el mercado, como ZeroMQ, Beanstalkd, etc.
Entonces, en lugar de consultar continuamente su base de datos, puede suscribirse a un evento de MQ y simplemente colgar hasta que alguien más publique un mensaje al que se suscribió y MQ lo despertará y le enviará un mensaje. La aplicación de chat es un muy buen caso de uso para comprender esta funcionalidad.
También debo mencionar que si busca las implementaciones de Comet-chat en otros idiomas, es posible que observe que algunas sencillas no utilizan MQ. Entonces, ¿cómo intercambian la información entonces? La cuestión es que tales soluciones generalmente se implementan como servidores asíncronos de un solo hilo, por lo que pueden almacenar todas las conexiones en una matriz local de subprocesos (o algo similar), manejar muchas conexiones en un solo bucle y simplemente elegir una y notificar cuando sea necesario. Tales implementaciones de servidores asíncronos son un enfoque moderno que se adapta realmente bien a la técnica Comet. Sin embargo, lo más probable es que esté implementando su Comet sobre mod_php o FastCGI, en este caso, este enfoque simple no es una opción para usted y debe usar MQ.
Esto todavía podría ser muy útil para entender cómo implementar un servidor cometa asíncrono independiente para manejar muchas conexiones en un solo hilo. Las versiones recientes de PHP son compatibles con Libevent y Socket Streams, por lo que también es posible implementar este tipo de servidor en PHP. También hay un example disponible en la documentación de PHP.
¿Cómo verifico los resultados durante la conexión Ajax que todavía está activa? Soy consciente de la función de éxito de jQuery para llamadas ajax, pero ¿cómo verifico los datos mientras la conexión aún está en curso?
Si está realizando sus encuestas de larga duración con una técnica de Ajax habitual, como XHR simple, jQuery Ajax, etc., no tiene una manera fácil de transmitir varias respuestas en una sola solicitud de Ajax. Como mencionó, solo tiene un controlador de "éxito" para tratar con la respuesta en su totalidad y no con su parte. Como solución, las personas envían una única respuesta por solicitud y la procesan en un controlador de "éxito", después de eso, simplemente abren una nueva solicitud de encuesta larga. Así es como funciona el protocolo HTTP.
También se debe mencionar que, en realidad, hay una solución alternativa para implementar una funcionalidad similar a la transmisión mediante el uso de diversas técnicas que utilizan técnicas como la página infinitamente larga en un IFRAME
oculto o el uso de respuestas HTTP de varias partes. Ambos métodos tienen ciertos inconvenientes (el primero se considera poco confiable y, a veces, puede producir un comportamiento no deseado del navegador, como el indicador de carga infinita, y el último tiene una compatibilidad consistente y directa con todos los navegadores, sin embargo, se sabe que ciertas aplicaciones aún confían en eso mecanismo que recurre al sondeo largo cuando el navegador no puede manejar adecuadamente las respuestas de varias partes).
Si desea manejar múltiples respuestas por solicitud / conexión única de una manera confiable, debe considerar el uso de una tecnología más avanzada, como WebSocket, que es compatible con los navegadores más actuales o en cualquier plataforma que admita sockets sin formato (como Flash o Si desarrolla para una aplicación móvil, por ejemplo).
¿Podría por favor elaborar más en las colas de mensajes?
Message Queue es un término que describe una implementación independiente (o integrada) del patrón Observer (también conocido como ''Publicar / Suscribir'' o simplemente PubSub). Si desarrolla una aplicación grande, tener una es muy útil: le permite desacoplar diferentes partes de su sistema, implementar un diseño asíncrono basado en eventos y hacer su vida mucho más fácil, especialmente en sistemas heterogéneos. Tiene muchas aplicaciones para los sistemas del mundo real, solo mencionaré algunas de ellas:
- Cola de tareas. Digamos que estamos escribiendo nuestro propio YouTube y necesitamos convertir los archivos de video de los usuarios en segundo plano. Obviamente, deberíamos tener una aplicación web con la interfaz de usuario para cargar una película y un número fijo de procesos de trabajo para convertir los archivos de video (tal vez incluso necesitemos un número de servidores dedicados donde solo se irán nuestros trabajadores). También probablemente tendríamos que escribir a nuestros trabajadores en C para garantizar un mejor rendimiento. Todo lo que tenemos que hacer es configurar un servidor de cola de mensajes para recopilar y entregar tareas de conversión de video desde la aplicación web a nuestros trabajadores. Cuando el trabajador genera, se conecta al MQ y se queda inactivo en espera de nuevas tareas. Cuando alguien carga un archivo de video, la aplicación web se conecta a la MQ y publica un mensaje con un nuevo trabajo. Los poderosos MQ, como RabbitMQ pueden distribuir igualmente las tareas entre la cantidad de trabajadores conectados, hacer un seguimiento de las tareas que se completaron, garantizar que no se pierda nada y proporcionar conmutación por error e incluso la interfaz de usuario de administración para examinar las tareas y estadísticas actuales pendientes.
- Comportamiento asíncrono. Nuestro Comet-chat es un buen ejemplo. Obviamente, no queremos sondear periódicamente nuestra base de datos todo el tiempo (¿para qué sirve Comet? No es una gran diferencia hacer solicitudes periódicas de Ajax). Preferiríamos que alguien nos notifique cuando aparece un nuevo mensaje de chat. Y una cola de mensajes es ese alguien. Digamos que estamos usando el almacén de valores / clave de Redis : esta es una herramienta realmente excelente que proporciona la implementación de PubSub entre sus características del almacén de datos. El escenario más simple puede verse como el siguiente:
- Después de que alguien ingresa a la sala de chat, se está realizando una nueva solicitud de encuesta larga de Ajax.
- El controlador de solicitud en el lado del servidor emite el comando a Redis para suscribir un canal ''newmessage''.
- Una vez que alguien ingresa un mensaje en su chat, el controlador del lado del servidor publica un mensaje en el tema "newmessage" de Redis.
- Una vez que se publique un mensaje, Redis notificará inmediatamente a todos aquellos manejadores pendientes que se suscribieron a ese canal anteriormente.
- Tras la notificación, el código PHP que mantiene abierta la solicitud de encuesta larga, puede devolver la solicitud con un nuevo mensaje de chat, por lo que todos los usuarios serán notificados. Pueden leer nuevos mensajes de la base de datos en ese momento, o los mensajes pueden transmitirse directamente dentro de la carga útil del mensaje.
Espero que mi ilustración sea fácil de entender; sin embargo, las colas de mensajes son un tema muy amplio, así que consulte los recursos mencionados anteriormente para obtener más información.