javascript - imprimir - Procesar un flujo continuo de JSON
mostrar datos json javascript (4)
La página (ahora difunta) http://stream.twitter.com/1/statuses/sample.json solía devolver un flujo continuo e infinito de datos JSON.
Me gustaría procesarlo usando jQuery (o JavaScript, pero preferiblemente jQuery) dentro de mi propia página web para poder mostrar efectos visuales basados en la transmisión en vivo de los tweets.
Por lo que sé, la función jQuery parseJSON
solo ejecutará la función de devolución de llamada una vez que el servidor haya enviado todos los datos, pero esto es en realidad un flujo continuo de datos. ¿Cómo puedo procesar los datos "a medida que ocurren" pero seguir manteniendo la conexión en funcionamiento?
La url que ha especificado en su pregunta envía un flujo de respuesta JSON. Debido a las restricciones de seguridad entre dominios en los navegadores, no puede acceder a él utilizando javascript. Deberá implementar una secuencia de comandos del lado del servidor de puente en su servidor, que podría realizar encuestas a intervalos regulares utilizando solicitudes AJAX o alojar su sitio en twitter.com
. Lo primero parece más factible.
Tengo un proyecto de código abierto que permite esto en los navegadores modernos (y se remonta a un estilo jQuery en los más antiguos). La sintaxis de la llamada es similar a jQuery.ajax:
Una página web a un nivel muy fundamental no puede mantener una conexión activa / en ejecución a un servidor. El navegador web envía una solicitud al servidor. El servidor envía una respuesta (el HTML y más) al cliente (navegador web). Piense en esto como un modelo sin estado: ninguna conexión se mantendrá viva después de que se haya completado la solicitud y la respuesta.
Por lo tanto, tienes que hacerlo tú mismo. Debe invocar solicitudes periódicas adicionales del lado del cliente.
Una forma sería llamar periódicamente a su funcionalidad AJAX / GET mediante la función setInterval() . Por ejemplo:
setInterval(function() {
$.ajax({
url: "mydata/get",
success: function(){
// update content.
}
});
}, 5000);
Esto activará una solicitud AJAX a mydata / get (o la URL que desee usar) cada 5 segundos.
Actualización 2
Este tipo de cosas se realiza mejor utilizando WebSockets ahora, que de acuerdo con CanIUse.Com está disponible en todos los navegadores principales, excepto en Opera Mini (vea ese enlace para obtener más detalles sobre los navegadores más antiguos o todos los demás, y haga clic en la pestaña Recursos para ver aún más enlaces) . Como resumen, los websockets son compatibles con IE 10+, Firefox 11+ (38+ si está dentro de un contexto de WebWorker), Chrome 16+, Opera 12.1+, Safari 7+, Android 4.4+, Opera Mobile 12.1+.
Se parece a esto:
var connection = new WebSocket(
''ws://html5rocks.websocket.org/echo'',
[''soap'', ''xmpp'']
);
Adjuntar algunos controladores de eventos inmediatamente a la conexión le permite saber cuándo se abre la conexión, cuándo recibió mensajes entrantes o si se produjo un error.
Enviar mensajes se vuelve tan fácil como esto:
connection.send(''your message'');
connection.send(binaryData);
Consulte WebSockets para obtener una explicación completa sobre cómo hacerlo.
Desarrolladores de ASP.Net: si por alguna razón necesita admitir navegadores más antiguos y no quiere descubrir por sí mismo cómo tratar con aquellos que no son compatibles con WebSockets, considere usar una biblioteca como SignalR .
La antigua respuesta de la API EventSource para navegadores más antiguos
La mayoría de los navegadores ahora implementan la API EventSource , lo que hace que el sondeo largo sea realmente fácil, siempre y cuando la secuencia se pueda entregar con text/event-stream
tipo contenido text/event-stream
. Los navegadores más antiguos o aquellos desarrolladores que, por cualquier motivo, no pueden diseñar la secuencia para tener ese tipo de contenido pueden usar un script de ayuda para hacer lo mismo.
Aquí hay un ejemplo:
var jsonStream = new EventSource(''https://example.com/yourstreamingservice'')
jsonStream.onmessage = function (e) {
var message = JSON.parse(e.data);
// handle message
};
Esto es básicamente una versión completa de la cosa exacta que describo a continuación.
La respuesta de transmisión de servicio aún más antigua para navegadores REALMENTE VIEJOS
Lo que quieres se llama sondeo largo. Necesitará una función de manejo de onreadystatechange
AJAX personalizada. En lugar de esperar hasta que todo el flujo se haya completado (ya que nunca lo hará), deberá examinar el contenido periódicamente. Tenga en cuenta que tendrá que hacer un trabajo pesado para que esto funcione en IE 9 e inferior, utilizando un iframe
.
Aproximadamente:
- Responde a cada evento
onreadystatechange
y examina la secuencia que has recibido hasta el carácter actual para ver si hay datos suficientes para consumir uno o más eventos discretos. Tendrá que analizar el flujo usted mismo con las funciones de manejo de cadenas de javascript. Se puede utilizar una combinación de split, indexOf, expresiones regulares, bucles, etc. para realizar esta tarea. - Si aún no hay suficiente contenido, salga y espere el próximo evento.
- Estoy bastante seguro de que cada vez que se
onreadystatechange
controladoronreadystatechange
, el texto deresponseText
será todos los datos que se han recibido hasta el momento. Defina una variable persistente que mantendrá la posición del primer carácter que aún no se haya procesado correctamente. - Una vez que haya suficiente contenido para que uno o más eventos discretos aparezcan en la transmisión, elimínelos de uno en uno y páselos al analizador JSON para representar el texto como objetos. Úsalos normalmente.
Echa un vistazo a esta lista de HTTP Streaming para un recurso, o Streaming como alternativa al sondeo del servidor en SoftwareAs. Si debe admitir IE 9 o una versión anterior, deberá usar el método iframe
para eso.
Aquí hay una cita del libro Ajax Design Patterns: Creación de sitios Web 2.0 con programación y patrones de usabilidad :
En resumen, Service Streaming hace que el enfoque de HTTP Streaming sea más flexible, ya que puede transmitir contenido arbitrario en lugar de comandos de Javascript, y porque puede controlar el ciclo de vida de la conexión. Sin embargo, combina dos tecnologías que no son consistentes en todos los navegadores, con problemas de portabilidad predecibles. Los experimentos sugieren que la técnica de transmisión de página funciona tanto en IE [9 y versiones posteriores] como en Firefox, pero la transmisión de servicio solo funciona en Firefox, ya sea que se use XMLHTTPRequest o IFrame. En el primer caso, IE [9 y más viejo] suprime la respuesta hasta que esté completa, con el IFrame funciona si se usa una solución alternativa: El IE [9 y más viejo] acepta un mensaje del servidor después de los primeros 256 bytes, así que lo único Lo que hay que hacer es enviar 256 bytes ficticios antes de enviar los mensajes. Después de esto todos los mensajes llegarán como se esperaba. ¡Así que también es posible una transmisión de servicio completa en IE [9 y más]!
Tenga en cuenta que es de 2006, por lo que definitivamente está desactualizado, pero si tiene que admitir navegadores más antiguos, sigue siendo relevante.
Temas de seguridad
El AJAX normal no puede ir de dominio cruzado, lo que significa (ahora que presto atención al hecho de que desea transmitir desde Twitter) que no podrá hacer lo que está pidiendo. Esto se puede solucionar con JSONP, pero JSONP por naturaleza no puede ser transmitido por el servicio y, de todos modos, no es ofrecido por Twitter de todos modos. También está el Intercambio de recursos de origen cruzado (CORS), pero Twitter no lo va a configurar, ese es el tipo de cosas que solo harían para los dominios afiliados a ellos. Y CORS requiere un navegador moderno.
Por lo tanto, su única opción es crear un servicio de proxy en su servidor web que realice las solicitudes de Twitter para usted y luego distribuya los datos. Esto solo se puede hacer desde el mismo dominio desde el que se sirvió la página principal. Hacer esto también le permitiría crear una versión que funcionará para IE usando la técnica de iframe. Si no le importan las versiones antiguas de IE, puede implementar CORS para anular la restricción de dominio, si conoce el dominio que realizará las solicitudes.
Si tiene el control total del software cliente (por ejemplo, si se trata de una intranet corporativa), existe otra opción: alojar el navegador web dentro de un formulario de usuario compilado de ejecución local. Solo he hecho esto usando C # pero me imagino que es posible desde otros idiomas. Cuando usa el objeto de navegador correcto, porque está alojado dentro de una aplicación C #, la aplicación C # puede anular las restricciones de seguridad entre dominios, leyendo y escribiendo todo el contenido de la página, sin importar de qué dominio proviene. Dudo que tu situación sea esta, pero quería poner la opción aquí para otros que puedan apreciarla.