2009-07-10 15 views
14

Página web de solicitud del cliente del servidor. Clent luego solicita que se hagan cálculos adicionales; el servidor realiza una serie de cálculos y envía resultados parciales tan pronto como estén disponibles (formato de texto, cada línea contiene un elemento completo por separado). Página web de actualizaciones del cliente (con JavaScript y DOM) utilizando la información proporcionada por el servidor.Implementación en varios navegadores de "HTTP Streaming" (push) Patrón AJAX

Esto parece ajustarse al modelo HTTP Streaming (current) del sitio Ajaxpatterns.

La pregunta es cómo hacerlo en modo cross-browser (navegador independiente), preferiblemente sin utilizar frameworks de JavaScript, o usando algún framework liviano como jQuery.

El problema comienza con la generación de XMLHttpRequest en la forma de navegador cruzado, pero creo que el elemento principal es que no todos los navegadores implementan correctamente onreadystatechange de XMLHttpRequest; no todos los navegadores llaman al evento onreadystatechange en cada descarga del servidor (por cierto, ¿cómo forzar el flujo del servidor desde el script CGI (en Perl)?). El código de ejemplo en Ajaxpatterns trata esto usando el temporizador; ¿Debo soltar la solución del temporizador si detecto una respuesta parcial de onreadystatechange?


Agregado 11-08-2009

solución actual:
utilizo la siguiente función para crear el objeto XMLHttpRequest:

function createRequestObject() { 
     var ro; 
     if (window.XMLHttpRequest) { 
       ro = new XMLHttpRequest(); 
     } else { 
       ro = new ActiveXObject("Microsoft.XMLHTTP"); 
     } 
     if (!ro) 
       debug("Couldn't start XMLHttpRequest object"); 
     return ro; 
} 

Si tuviera que utilizar Algún marco de JavaScript (preferiblemente liviano) como jQuery, me gustaría tener respaldo si el usuario elige no instalar jQuery.

Utilizo el siguiente código para iniciar AJAX; setInterval se usa porque algunos navegadores llaman al onreadystatechange solo después de que el servidor cierra la conexión (que puede tomar tanto tiempo como decenas de segundos), y no tan pronto como el servidor vacía datos (cada segundo o más a menudo).

function startProcess(dataUrl) { 
     http = createRequestObject(); 
     http.open('get', dataUrl); 
     http.onreadystatechange = handleResponse; 
     http.send(null); 

     pollTimer = setInterval(handleResponse, 1000); 
} 

La función handleResponse es más complicado, pero el esbozo de ella tiene el siguiente aspecto. ¿Se puede hacer mejor? ¿Cómo se haría usando un marco de JavaScript liviano (como jQuery)?

function handleResponse() { 
    if (http.readyState != 4 && http.readyState != 3) 
     return; 
    if (http.readyState == 3 && http.status != 200) 
     return; 
    if (http.readyState == 4 && http.status != 200) { 
     clearInterval(pollTimer); 
     inProgress = false; 
    } 
    // In konqueror http.responseText is sometimes null here... 
    if (http.responseText === null) 
     return; 

    while (prevDataLength != http.responseText.length) { 
     if (http.readyState == 4 && prevDataLength == http.responseText.length) 
      break; 
     prevDataLength = http.responseText.length; 
     var response = http.responseText.substring(nextLine); 
     var lines = response.split('\n'); 
     nextLine = nextLine + response.lastIndexOf('\n') + 1; 
     if (response[response.length-1] != '\n') 
      lines.pop(); 

     for (var i = 0; i < lines.length; i++) { 
      // ... 
     } 
    } 

    if (http.readyState == 4 && prevDataLength == http.responseText.length) 
     clearInterval(pollTimer); 

    inProgress = false; 
} 
+0

Definitivamente debe añadir que el ejemplo de código como respuesta y marcarla como el correcto! –

+4

"si el usuario elige no instalar jQuery"? – Basic

+0

Hola, acabo de encontrar su solución, pero me temo que todavía no funciona con IE, ya que cuando se le trata de obtener el responseText mientras que las solicitudes aún no había terminado, entonces obtendrá el siguiente mensaje: "Los datos necesarios para completar esta operación aún no están disponibles". –

Respuesta

2

La solución se enlazó a AJAX no es en absoluto, en realidad. Lo llaman HTTP Streaming, pero esencialmente es solo un largo sondeo.

En el ejemplo al que se vinculan, puede verlo con bastante facilidad con Firebug. Active el panel Red - no hay entradas XHR, pero lleva solo un pelo más de 10 segundos cargar la página original. Eso es porque están usando PHP detrás de escena para retrasar la salida del HTML. Esta es la esencia de las encuestas largas: la conexión HTTP permanece abierta y el HTML periódico enviado de vuelta es un comando de javascript.

Puede optar por hacer el sondeo por completo en el lado del cliente, sin embargo, con setTimeout() o setInterval()

Un ejemplo jQuery

<script type="text/javascript"> 
    $(document).ready(function() 
    { 
    var ajaxInterval = setInterval(function() 
    { 
     $.getJSON(
     'some/servie/url.ext' 
     , { sample: "data" } 
     , function(response) 
      { 
      $('#output').append(response.whatever);   
      } 
    ); 
    }, 10000); 
    }); 
</script> 
+0

No exactamente lo que quiero. El cálculo en el servidor genera resultados en formato de texto sin formato. Con XHR puedo obtener esta respuesta directamente en el cliente (onreadystatechange on flush/timer) y edito la página web según los datos parciales que obtengo. –

+0

¿Qué es lo que no quieres? La larga encuesta? No recomiendo ninguno de los dos métodos: solo te digo cuáles son tus opciones. –

+0

En caso de que quiera utilizar siempre puesta en común (Comet), se debe considerar el uso de software de servidor Meteor, porque Apache no está diseñado para que ese tipo de cosas. Y también hay una biblioteca javascript que maneja casi todo por ti, simplemente no puedo recordar su nombre, lo publicaré más tarde. – usoban

0

me gustaría echar un vistazo en órbita

ellos usan varios aplicación transporte cometa que seleccionar en función de la configuración y browser sniffing.

Ver http://orbited.org/svn/orbited/trunk/daemon/orbited/static/Orbited.js

y busque "Orbited.CometTransports"

Algunos de los diferentes medios de transporte debe ir acompañada de la aplicación de back-end, así que echar un vistazo a la parte del servidor de órbita también.

Cuestiones relacionadas