Heim  >  Artikel  >  Backend-Entwicklung  >  Der HTTP-Browser trennt aktiv die Verbindung und der PHP-Browser trennt aktiv die Verbindung

Der HTTP-Browser trennt aktiv die Verbindung und der PHP-Browser trennt aktiv die Verbindung

不言
不言Original
2018-04-26 14:41:214963Durchsuche

In diesem Artikel erfahren Sie, wie der http-Browser aktiv getrennt wird und PHP aktiv getrennt wird. Interessierte Freunde können einen Blick darauf werfen

Zusammenfassung: Die Ursache des Vorfalls ist auf die üblichen Zweifel bei der Entwicklung zurückzuführen. Einmal, nachdem der Browser-Client aktiv die Verbindung getrennt hatte, wurde festgestellt, dass das serverseitige PHP-Skript immer noch ausgeführt wurde, sodass ich nicht wusste, wie ich das Skript stoppen sollte. Ein anderes Mal musste das PHP-Skript aktiv getrennt werden und die nachfolgenden Skripte wurden dann weiter ausgeführt (eine zeitaufwändige Aufgabe), weshalb dieser Blog erstellt wurde.

1. Der Browser trennt aktiv die Verbindung

Unter der häufig verwendeten LAMP-Kombination gehen wir davon aus, dass der Browser auf ein PHP-Skript zugreift, das Skript mit der Ausführung beginnt, das Skript Inhalte ausgibt und die Ausführung beendet, Apache Als Antwort auf http empfängt der Browser die http-Antwort und zeigt das Ergebnis an.
Betrachten wir besondere Situationen.
1. Der Browser sendet eine http-Anfrage und PHP führt eine zeitaufwändige Aufgabe aus (20 Sekunden) (vorausgesetzt, PHPs set_time_limit ist auf 30 Sekunden eingestellt, und der Browser antwortet nicht). Der Benutzer klickt auf den Browser X, der Browser trennt aktiv die Verbindung. Läuft das PHP-Skript weiterhin?
Angenommen, die zeitaufwändige Aufgabe lautet: Berechnen Sie fib (25). Die Browsertestantwort dauert 1,15 Sekunden. Bei jeder Ausführung der zeitaufwändigen Aufgabe wird das Dateiprotokoll einmal geschrieben und die zeitaufwändige Aufgabe ausgeführt 10 Mal und nach der fünften Ausführung. Zu diesem Zeitpunkt trennt sich der Client aktiv und beobachtet die Situation.
Der Code lautet wie folgt:

<?phpfor ($i=0; $i < 10; $i++) { 
    fib(25);
    setLog(date(&#39;H:i:s&#39;));
}function fib($n = 3){
    if($n == 0){        return 1;
    }    if($n == 1){        return 1;
    }    return fib($n - 1) + fib($n -2);
}function setLog( $massage, $path=&#39;&#39;){
    $log_path = empty($path)?&#39;./log_&#39;.date(&#39;Y-m-d&#39;).&#39;.log&#39;:$path;    $time = date(&#39;Y-m-d H:i:s&#39;);    $error_page = &#39;http://&#39; . $_SERVER[&#39;HTTP_HOST&#39;] . $_SERVER[&#39;REQUEST_URI&#39;];
    file_put_contents($log_path, "LOG TIME:".$time.PHP_EOL, FILE_APPEND);
    file_put_contents($log_path, "LOG URL:".$error_page.PHP_EOL, FILE_APPEND);    if(is_array($massage)){        $massage = json_encode($massage);
    }
    file_put_contents($log_path, "LOG MESSAGE:".$massage.PHP_EOL.PHP_EOL, FILE_APPEND);
}?>

  Der Browser wurde getrennt, als die Ausführung 5,44 Sekunden erreichte.
 Das Protokoll zeigt: Das Skript hat 10 Zyklen abgeschlossen.
 Das unterscheidet sich von dem, was wir vorher gedacht haben.

  2. Ich habe gesehen, dass PHP bestimmt, ob die Client-Verbindung getrennt wird, wenn PHP Inhalte an den Client ausgibt > beurteilt wird, ändern wir dann den Testcode:

 Testen Sie erneut und stellen Sie fest, dass die Ergebnisse mit denen des letzten Tests identisch sind. Der Grund: Wenn PHP Inhalte an den Client ausgibt, gibt es drei Pufferstufen, nämlich:
<phpfor ($i=0; $i < 10; $i++) { 
    fib(25);    setLog(date(&#39;H:i:s&#39;));    echo "hello";
}

//这里省略了fib和setLog函数
?>
  PHP-Puffer => Webserver-Puffer => Browser-Puffer

  Nur wenn der Puffer voll ist Es wird an den Client ausgegeben. Dies ist eigentlich das Prinzip, dass das Back-End von Zeit zu Zeit Inhalte an das Front-End ausgibt. Natürlich können Sie die Ausgabe an den Client auch dann steuern, wenn der Puffer nicht voll ist.

   

3. Ändern Sie den Testcode erneut, um die Inhaltsausgabe an den Client groß genug zu machen:

  Testen Sie dieses Mal erneut und Sie werden feststellen, dass der Browser wird nach einer Weile neu gestartet. Ich habe einige Antworten anstelle der vorherigen Demo erhalten, die erforderte, dass das Skript vollständig ausgeführt wurde, bevor der Inhalt an den Client ausgegeben wurde. Gleichzeitig wird die Client-Verbindung zu diesem Zeitpunkt geschlossen. Wenn der Server erneut Inhalte an den Client ausgibt, prüft er, ob die Client-Verbindung getrennt wurde. Zu diesem Zeitpunkt wird die Ausführung des Skripts gestoppt. Das ist das Testergebnis, das wir wollen.
<?php$re = "";for($i=0; $i < 10000; $i++){    $re .= "aa";
}for ($i=0; $i < 10; $i++) { 
    fib(25);
    setLog(date(&#39;H:i:s&#39;));    echo $re;
}//这里省略了fib和setLog函数?>

  

4. Ändern Sie den Testcode erneut, anstatt eine große Menge an Inhalten gleichzeitig auszugeben, wird der Inhalt des Puffers absichtlich so manipuliert, dass der Inhalt nicht ausreicht Die Ausgabe aus dem Puffer an den Client wird vorab an den Client ausgegeben.

Testcode:

Zusammenfassung:
for ($i=0; $i < 10; $i++) { 
    fib(25);    setLog(date(&#39;H:i:s&#39;));    echo "hello " . date(&#39;H:i:s&#39;) . "<br>";
    ob_flush();
    flush();
}
//这里省略了fib和setLog函数

    Im Prinzip trennt sich der Client aktiv und das PHP-Skript wird nicht mehr ausgeführt 🎜>
  • Aber die Voraussetzung ist, dass PHP weiß, wie der Client die Verbindung trennt. Nur wenn PHP Inhalte an den Client ausgibt (nicht an den PHP-Puffer, nicht an den Webserver-Puffer), erkennt PHP, dass der Client nicht mehr ausgeführt wird nur wenn die Verbindung unterbrochen ist;

  • Es gibt zwei Möglichkeiten für PHP, Inhalte an den Client auszugeben. Die erste besteht darin, den Inhalt in den Puffer zu füllen und ihn automatisch an den Client zu senden. Die zweite besteht darin, ob_flush, die Flush-Funktion, zu verwenden, um den Pufferinhalt aktiv an den Client zu senden Die Ausführung des PHP-Skripts unterliegt auch internen Änderungen. Das Skript-Timer-Limit kann in php.ini oder der Host-Apache-Konfigurationsdatei konfiguriert oder über die Funktion set_time_limt im Skript festgelegt werden Wenn der Client die Verbindung trennt, wird die Ausführung des PHP-Skripts auch durch den Skript-Timer begrenzt.

  • Wenn das PHP-Skript „ignore_user_abort(true);“ Verbindung ist getrennt, PHP gibt Inhalte an den Client aus. Auch wenn der Client weiß, dass die Client-Verbindung getrennt ist, wird die Skriptausführung nicht gestoppt

  • Intern in PHP wird der Verbindungsstatus von beibehalten Das System kann über den Rückgabewert der Funktion „connection_status“ überprüft werden. 0: normal; 2: Zeitüberschreitung. Die Erkennung eines geänderten Status erfordert auch, dass das PHP-Skript den Inhalt an den Client ausgibt immer 0 sein;

  • Zusätzlich gibt es eine Funktion, die auch erkennen kann, ob die Client-Verbindung getrennt ist (connection_aborted), 0 ist normal, 1 ist getrennt.

  • Ein seltsames Problem besteht darin, dass das Statusbit 1 wird, wenn die Client-Verbindung getrennt wurde und das PHP-Skript zweimal ausgegeben wird 2. Der PHP-Server trennt aktiv die Verbindung

  • Um PHP aktiv zu trennen, verwenden Sie die Felder „content-length“ und „connection“ im HTTP-Antwortheader mit der folgenden Bedeutung:
  • Inhaltslänge: Wenn der Client die Inhaltslänge des Antwortheaders empfängt und der entsprechende Text die angegebene Größe erhält, wird er vom Server getrennt
  • connection,当客户端收到响应头connection的值为close或者keep-alive,决定关闭当前tcp连接或者继续使用当前连接作下一次请求;

  • 测试发现,当只指定conetent-length的时候也能达到php主动断开连接;

  • 其实说是php主动断开连接,其实是php通知客户端主动断开的连接;

示例代码:

<?phpecho "hello world";

test();for ($i=0; $i < 10; $i++) { 
    fib(25);
    setLog(date(&#39;H:i:s&#39;));
}function test(){
    $size = ob_get_length();
    header("content-length:" . $size);    //header("connection:close");
    ob_flush();
    flush();
}//这里省略了fib和setLog函数?>



ba33df4ef3efea3726e09756c08771e7



Das obige ist der detaillierte Inhalt vonDer HTTP-Browser trennt aktiv die Verbindung und der PHP-Browser trennt aktiv die Verbindung. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn