2009-10-09 8 views
5

Ich bin verantwortlich für den Backend-Teil einer API, geschrieben in PHP, die hauptsächlich von einem Flash-Client verwendet wird. Was jetzt passiert ist: Der Flash-Client ruft an, das Backend lädt die notwendigen Daten, führt alle notwendigen Verarbeitungen und Nachbearbeitungen, Logging und Caching durch und gibt das Ergebnis an den Client zurück.PHP + gzip: Verbindung schließen und weiter ausführen

Was ich gerne geschehen würde, ist so schnell wie möglich die Daten an den Client zurück zu geben, die Verbindung zu schließen, und dann alle Sachen, die der Client nicht kümmern muss. Dadurch könnte die API viel schneller reagieren. Im Anschluss an hier die Vorschläge:

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

tatsächlich funktioniert, außer, dass ich zu gzip-Codierung, um auszuschalten, damit es funktioniert, was nicht sehr praktisch ist. Wir verwenden mod_deflate in Apache, also wäre eine Lösung, die damit arbeitet, ideal, aber ich würde auch eine andere Methode in Erwägung ziehen, unseren Inhalt zu gzip, wenn das notwendig ist.

Es scheint wie es sollte eine Möglichkeit sein, Apache wissen zu lassen "Ich habe dir alle Daten gesendet, die ich senden werde", aber ich kann nicht scheinen, etwas ähnliches zu finden.

Für diejenigen, die fragen, ja, ich kann die Ergebnisse früh, aber der Flash-Client wird sie nicht verarbeiten, bis die Verbindung geschlossen ist.

Antwort

3

Sie könnten versuchen, es in zwei Seiten zu brechen.

In der ersten Seite, machen Sie die notwendige Verarbeitung, dann laden Sie die zweite Seite über curl, und sterben().

Dies würde dazu führen, dass die erste Seite unabhängig von der Verarbeitung der zweiten Seite abgeschlossen und geschlossen wird.

dh:

Seite 1:

Seite 2:

<?php 

// Do other stuff.... 

?> 

http://www.php.net/curl

+0

Dank. Ich kenne einige Problemumgehungen für dieses Problem, einige eleganter als andere, aber ich würde gerne einen Weg finden, Apache einfach zu sagen, dass er nicht mehr auf die Ausgabe warten und die Verbindung schließen soll. :) –

0

Es gibt eine Art von Hack Sehen Sie, dies zu tun, indem Sie den Code platzieren Sie wollen ausgeführt werden, nachdem die Verbindung innerhalb einer überregistrierten Callback-Methode geschlossen wurde

+0

Ooh, glänzend! Ich werde das morgen versuchen. –

+0

Kein Glück. Der folgende Ausdruck druckt den zusätzlichen Mist aus und benötigt die volle Ausführungszeit, um die Verbindung zu schließen, wenn mod_deflate verwendet wird: Funktion sleepLongTime() {print "Sie können dies nicht sehen"; Schlaf (30); } ob_end_clean(); register_shutdown_function ('sleepLongTime'); header ("Verbindung: schließen \ r \ n"); ignore_user_abort (wahr); ob_start(); echo ('Text Benutzer wird sehen'); ob_end_flush(); bündig(); ob_end_clean(); sterben(); –

0

@ Theo.T da das Kommentarsystem den Mist aus meinem Code verstümmelt, ich bin Entsendung es hier:

Kein Glück. Die folgenden druckt die zusätzlichen Mist und nimmt die volle Ausführungszeit die Verbindung zu schließen, wenn mod_deflate mit:

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(); 

wird dies dem Benutzer mitteilen, die Verbindung, sobald alle $stream empfangen zu schließen. aber vorsichtig sein, nichts vor dem header Teil u wissen: p

Wenn Sie binäre Daten (SWF) senden müssen Sie möglicherweise die "+256" und echo(str_repeat(' ',256)); entfernen, aber in diesem Fall der Code "möglicherweise" fehlschlagen wenn die gesendeten Daten weniger als 256 Bytes sind.

-1

heute auch diesen Fall, den ich traf, nach einigen Tests um, fand ich diese Art und Weise funktioniert:

Zwei Schritte:

  1. die Lösung der PHP-Skript-Ausgabe ist Achten Sie darauf, nicht mit gzip-Codierung, siehe kann dieses link:

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

die oben .htaccess Datei unter der prj Website hinzufügen, dann Apache gzip vermeiden es automatisch.

  1. Da einige Leute sagten, bei 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

Er fordert gzip an und du gibst keine gzip-Antwort ... das hilft nicht. – brunoais