2009-10-09 15 views
5

Soy responsable de la parte backend de una API, escrita en PHP, que es utilizada principalmente por un cliente Flash. Lo que sucede en este momento es: el cliente Flash realiza una llamada, el servidor carga los datos necesarios, procesa y postprocesa, registra y almacena en caché y luego devuelve el resultado al cliente.PHP + gzip: cerrar la conexión y continuar ejecutando

Lo que me gustaría que suceda es devolver los datos al cliente lo antes posible, cerrar la conexión y luego hacer todo lo que el cliente no tiene que preocuparse. Esto podría hacer que la API parezca mucho más receptiva. Siguiendo las sugerencias aquí:

http://php.net/manual/en/features.connection-handling.php

realmente funciona, excepto que tengo que desactivar la codificación gzip con el fin de hacer que funcione, que no es muy práctico. Usamos mod_deflate en apache, por lo que una solución que funcione con eso sería ideal, pero también consideraría un método diferente para descomprimir nuestro contenido si fuera necesario.

Parece parece que parece que hay una manera de que Apache sepa "le he enviado todos los datos que voy a enviar", pero parece que no puedo encontrar algo así.

Para aquellos que se preguntan, sí puedo lavar los resultados anticipadamente, pero el cliente Flash no los procesará hasta que se cierre la conexión.

Respuesta

3

Puede tratar de dividirlo en dos páginas.

En la primera página, haga el procesamiento necesario, luego cargue la segunda página mediante curl y muera().

Eso haría que la primera página se complete y se cierre, independientemente del procesamiento de la segunda página.

es decir:

Página 1:

Página 2:

<?php 

// Do other stuff.... 

?> 

Ver http://www.php.net/curl

+0

Gracias. Soy consciente de algunas soluciones para este problema, algunas más elegantes que otras, pero realmente me gustaría encontrar la manera de decirle a Apache que deje de esperar la salida y cierre la conexión. :) –

0

Hay una especie de truco para hacer esto colocando el código que desea para ejecutar después de que la conexión se cierra dentro de un método de devolución de llamada registrado a través del register_shutdown_function();

+0

Ooh, brillante! Lo intentaré mañana. –

+0

Sin suerte. Lo siguiente imprime la basura extra y toma todo el tiempo de ejecución para cerrar la conexión cuando se utiliza mod_deflate: función sleepLongTime() {print "no se puede ver esto"; dormir (30); } ob_end_clean(); register_shutdown_function ('sleepLongTime'); encabezado ("Conexión: cerrar \ r \ n"); ignore_user_abort (true); ob_start(); echo ('El usuario de texto verá'); ob_end_flush(); flush(); ob_end_clean(); morir(); –

0

@ Theo.T ya que el sistema de comentarios destrozado a la mierda de mi código, he publicado aquí:

No hubo suerte. Los siguientes imprime la basura adicional y se toma el tiempo de ejecución completo para cerrar la conexión cuando se utiliza mod_deflate:

function sleepLongTime() { 
    print "you can't see this"; 
    sleep(30); 
} 
ob_end_clean(); 
register_shutdown_function('sleepLongTime'); 
header("Connection: close\r\n"); 
ignore_user_abort(true); 
ob_start(); 
echo ('Text user will see'); 
ob_end_flush(); 
flush(); 
ob_end_clean(); 
die(); 
0
set_time_limit(0); 
header("Connection: close"); 
header("Content-Length: " .(strlen($stream)+256)); 
ignore_user_abort(true); 

echo $stream; 
echo(str_repeat(' ',256)); 
@ob_flush(); 
@flush(); 
@ob_end_flush(); 

your_long_long_long_long_function_here(); 

esto le dirá al usuario que cierre la conexión una vez que todos $stream se recibe. pero tenga cuidado de no repetir nada antes de la parte header, sepa: p

si está enviando datos binarios (swf) es posible que necesite eliminar el '+256' y el echo(str_repeat(' ',256)); pero en este caso el código 'podría' fallar si los datos enviados son menos de 256 bytes.

-1

Hoy en día también conocí este caso, después de algunas pruebas de todo, he encontrado esta forma de trabajar:

Dos pasos:

  1. Asegúrese de que la salida del script php no es con gzip codificación, la solución puede hacer referencia a esta link:

    <IfModule mod_env.c>
    SetEnvIfNoCase Request_URI "\.php$" no-gzip dont-vary
    </IfModule>

Añadir a lo anterior .htaccess archivo con el sitio web prj, entonces es mejor evitar gzip Apache automáticamente.

  1. Como algunas personas dijeron que al features.connection-handling.php,

    set_time_limit(0); 
    ignore_user_abort(true);  
    // buffer all upcoming output - make sure we care about compression: 
    if(!ob_start("ob_gzhandler")) 
        ob_start();   
    echo $stringToOutput;  
    // get the size of the output 
    $size = ob_get_length();  
    // send headers to tell the browser to close the connection  
    header("Content-Length: $size"); 
    header('Connection: close');  
    // flush all output 
    ob_end_flush(); 
    ob_flush(); 
    flush();  
    // close current session 
    if (session_id()) session_write_close(); //close connection 
    
    // here, do what you want. 
    
+0

Solicita gzip y usted da una respuesta sin gzip ... eso no ayuda. – brunoais

Cuestiones relacionadas