Maison > Article > développement back-end > Le navigateur http se déconnecte activement et PHP se déconnecte activement
Cet article partage avec vous la déconnexion active du navigateur http et la déconnexion active de php. Les amis intéressés peuvent y jeter un œil
Résumé : La cause de l'incident est due à la rencontre habituelle lors de doutes sur le développement. Une fois, après la déconnexion active du client du navigateur, il a été constaté que le script php côté serveur était toujours en cours d'exécution, je ne savais donc pas comment arrêter le script. Une autre fois, il était nécessaire de déconnecter activement le script php, puis les scripts suivants continuaient à s'exécuter (une tâche qui prenait beaucoup de temps), c'est pourquoi ce blog a été créé.
Sous la combinaison LAMP couramment utilisée, nous pensons que le navigateur accède à un script php, le script commence à s'exécuter, le script génère du contenu et termine son exécution, Apache En réponse à http, le navigateur reçoit la réponse http et affiche le résultat.
Considérons des situations particulières.
1. Le navigateur envoie une requête http, et PHP effectue une tâche fastidieuse (20s) (en supposant que le set_time_limit de PHP est défini sur 30s. Pendant cette période, le navigateur ne répond pas et). l'utilisateur clique sur le navigateur X, le navigateur se déconnecte activement, le script php continue-t-il de s'exécuter ?
Supposons que la tâche fastidieuse soit : calculer fib(25), la réponse du test du navigateur prend 1,15 s, chaque fois que la tâche fastidieuse est exécutée, le fichier Log est écrit une fois, la tâche fastidieuse est exécutée 10 fois, et après la cinquième exécution. A ce moment, le client se déconnecte activement et observe la situation.
Le code est le suivant :
<?phpfor ($i=0; $i < 10; $i++) { fib(25); setLog(date('H:i:s')); }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=''){ $log_path = empty($path)?'./log_'.date('Y-m-d').'.log':$path; $time = date('Y-m-d H:i:s'); $error_page = 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']; 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); }?>
Le navigateur s'est déconnecté lorsque l'exécution a atteint 5,44s.
Le journal indique : Le script a terminé 10 cycles.
C'est différent de ce que nous pensions auparavant ;
2. J'ai vu qu'il était dit en ligne que PHP détermine si la connexion client est déconnectée lorsque PHP envoie du contenu au client est jugé, puis nous modifions le code du test :
<phpfor ($i=0; $i < 10; $i++) { fib(25); setLog(date('H:i:s')); echo "hello"; } //这里省略了fib和setLog函数 ?>Testez à nouveau et constatez que les résultats sont les mêmes que le dernier test. La raison : lorsque php envoie du contenu au client, il y a trois étapes de mise en mémoire tampon, à savoir :
tampon php => tampon du serveur Web => tampon du navigateur
Uniquement lorsque le tampon est plein, il sera envoyé au client. C’est en fait le principe selon lequel le back-end envoie du contenu au front-end de temps en temps. Bien entendu, vous pouvez également contrôler la sortie vers le client lorsque le tampon n'est pas plein.
3. Modifiez à nouveau le code de test pour que le contenu envoyé au client soit suffisamment volumineux :
<?php$re = "";for($i=0; $i < 10000; $i++){ $re .= "aa"; }for ($i=0; $i < 10; $i++) { fib(25); setLog(date('H:i:s')); echo $re; }//这里省略了fib和setLog函数?>Testez à nouveau cette fois et vous constaterez que le navigateur va redémarrer après un certain temps. J'ai reçu des réponses, au lieu de la démo précédente, qui nécessitait que le script soit entièrement exécuté avant de transmettre le contenu au client. En même temps, la connexion client est fermée à ce moment-là. Lorsque le serveur envoie à nouveau du contenu au client, il vérifiera que la connexion client a été déconnectée. À ce moment, le script cessera de s'exécuter. C'est le résultat du test que nous voulons.
4. Modifiez à nouveau le code de test cette fois, au lieu de sortir une grande quantité de contenu à la fois, le contenu du tampon est délibérément manipulé pour que le contenu ne soit pas suffisant. la sortie du tampon vers le client est envoyée au client à l'avance. Code de test :
for ($i=0; $i < 10; $i++) { fib(25); setLog(date('H:i:s')); echo "hello " . date('H:i:s') . "<br>"; ob_flush(); flush(); } //这里省略了fib和setLog函数Résumé :
;
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('H:i:s')); }function test(){ $size = ob_get_length(); header("content-length:" . $size); //header("connection:close"); ob_flush(); flush(); }//这里省略了fib和setLog函数?>
ba33df4ef3efea3726e09756c08771e7
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!