這篇文章給大家分享了http 瀏覽器主動斷開連接與php主動斷開連接,有興趣的朋友可以看一看
摘要:事件起因是因為平時在開發中遇到的疑惑。一次是瀏覽器客戶端主動斷開了連線後,發現伺服器端的php腳本還在執行,以至於不知道怎麼讓腳本停下來。還有一次是有需求讓php腳本主動斷開連接,然後後續腳本繼續執行(一個耗時任務),所以有了這篇部落格。
一、瀏覽器主動斷開連接
在常用的LAMP組合下,我們認為,瀏覽器訪問一個php腳本,腳本開始執行,腳本輸出內容,並結束運行,apache回應http,瀏覽器收到http回應,顯示結果。
下來考慮下特殊的情況。
1、瀏覽器發送http請求,php執行了一個耗時任務(20s)(假設php的set_time_limit設定的是30s),在此期間瀏覽器無回應,使用者點擊瀏覽器X,瀏覽器主動斷開連接,php腳本是否仍繼續運作。
假設耗時任務是:計算fib(25),瀏覽器測試回應需要時間1.15s,每執行一次耗時任務,寫檔案Log寫一次,執行10次耗時任務,在執行第5次的時候,客戶端主動斷開連接,觀察情況。
程式碼如下:
<?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); }?>
瀏覽器在執行到5.44s的時候斷開了連線。
日誌顯示:腳本執行完了10次迴圈。
這與我們之前認為的不一樣;
2、優化一下,看到網上說,php判斷客戶端連接是否斷開,是在php往客戶端輸出內容的時候判斷的,那我們把測試程式碼修改一下:
<phpfor ($i=0; $i < 10; $i++) { fib(25); setLog(date('H:i:s')); echo "hello"; } //这里省略了fib和setLog函数 ?>
再次測試一下,發現和上一次的測試結果是一樣的。究其原因:php往客戶端輸出內容的時候,要有3個緩衝階段,分別是:
php buffer => web server buffer => browser buffer
只有當緩衝區滿了的時候才會輸出到客戶端,其實就是,後端每隔一段時間就會輸出內容到前端的原理。當然也是可以控制當緩衝區沒有滿的時候,也讓輸出到客戶端。
3、再修改測試程式碼,讓輸出客戶端的內容夠大:
<?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函数?>
這次再測試,就會發現瀏覽器會隔一段時間就收到一些相應,而不是之前的demo,需要腳本完全執行完才輸出內容到客戶端。同時,這個時候關閉客戶端連接,伺服器端當再次向客戶端輸出內容的時候,就會檢查客戶端連接已經斷開了,這個時候腳本就會停止運行了。這是我們想要的測試結果。
4、再修改測試程式碼,這次不讓一次輸出一個很大的內容,而是有意操作緩衝區內容,讓雖然不夠從緩衝區輸出到客戶端的內容提前輸出到客戶端。
測試程式碼:
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函数
小結:
#原則上用戶端主動斷開連接,php腳本即停止執行;
- php輸出內容到客戶端,有兩種方式。一是填滿內容到緩衝區自動傳送到客戶端;二是使用ob_flush,flush函數主動將緩衝區內容沖刷給客戶端;
- php腳本運行還受到內部的腳本計時器限制,可以在php.ini或宿主apache設定檔中配置,或腳本中透過set_time_limt函數設定;
- 當客戶端主動斷開連接,而php腳本沒有停止運作的時候,還要受限於腳本計時器;
- 當php腳本設定ignore_user_abort(true); 則即使客戶端連線斷開,且php輸出內容到客戶端知道了客戶端連線斷開,也不會停止腳本執行;
- php內部,系統維護的連線狀態,可以透過函數connection_status的回傳值檢查,0 : normal; 1 : aborted(斷開連線); 2 : timeout; 改變狀態的偵測也是需要php腳本輸出內容到客戶端才會知道,否則一直都是0;
- ##另外還有一個函數也可以偵測客戶端連線是否斷開(connection_aborted),0正常,1斷開。
- 有個奇怪的問題是,當客戶端連線已經斷開,php腳本輸出兩次後,狀態位元才變成1;
二、php伺服器端主動斷開連接 要讓php主動斷開連接,要使用http回應頭裡面的content-length和connection兩個字段,意義分別為:
- content-length,當客戶端收到的回應頭content-length,則當對應體收到指定大小後,就會中斷與伺服器的連線;###
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函数?>
以上是http 瀏覽器主動斷開連接 與 php主動斷開連接的詳細內容。更多資訊請關注PHP中文網其他相關文章!

Springboot内置tomcat禁止不安全HTTP方法1、在tomcat的web.xml中可以配置如下内容让tomcat禁止不安全的HTTP方法/*PUTDELETEHEADOPTIONSTRACEBASIC2、Springboot使用内置tomcat没有web.xml配置文件,可以通过以下配置进行,简单来说就是要注入到Spring容器中@ConfigurationpublicclassTomcatConfig{@BeanpublicEmbeddedServletContainerFacto

1.HttpURLConnection使用JDK原生提供的net,无需其他jar包,代码如下:importcom.alibaba.fastjson.JSON;importjava.io.BufferedReader;importjava.io.InputStream;importjava.io.InputStreamReader;importjava.io.OutputStream;importjava.net.HttpURLConnection;

要在UbuntuLinux中删除FirefoxSnap,可以按照以下步骤进行操作:打开终端并以管理员身份登录到Ubuntu系统。运行以下命令以卸载FirefoxSnap:sudosnapremovefirefox系统将提示你输入管理员密码。输入密码并按下Enter键以确认。等待命令执行完成。一旦完成,FirefoxSnap将被完全删除。请注意,这将删除通过Snap包管理器安装的Firefox版本。如果你通过其他方式(如APT包管理器)安装了另一个版本的Firefox,则不会受到影响。通过以上步骤

一、前言#ssl写在443端口后面。这样http和https的链接都可以用listen443sslhttp2default_server;server_namechat.chengxinsong.cn;#hsts的合理使用,max-age表明hsts在浏览器中的缓存时间,includesubdomainscam参数指定应该在所有子域上启用hsts,preload参数表示预加载,通过strict-transport-security:max-age=0将缓存设置为0可以撤销hstsadd_head

httpkeepalive在http早期,每个http请求都要求打开一个tpcsocket连接,并且使用一次之后就断开这个tcp连接。使用keep-alive可以改善这种状态,即在一次tcp连接中可以持续发送多份数据而不会断开连接。通过使用keep-alive机制,可以减少tcp连接建立次数,也意味着可以减少time_wait状态连接,以此提高性能和提高httpd服务器的吞吐率(更少的tcp连接意味着更少的系统内核调用,socket的accept()和close()调用)。但是,keep-ali

一、urllib概述:urllib是Python中请求url连接的官方标准库,就是你安装了python,这个库就已经可以直接使用了,基本上涵盖了基础的网络请求功能。在Python2中主要为urllib和urllib2,在Python3中整合成了urllib。Python3.x中将urllib2合并到了urllib,之后此包分成了以下四个模块:urllib.request:它是最基本的http请求模块,用来模拟发送请求urllib.error:异常处理模块,如果出现错误可以捕获这些异常urllib

mozilla firefox可以卸载;firefox属于第三方浏览器,如果不需要,完全可以卸载。卸载方法:1、在开始菜单中,依次点击“Windwos系统”-“控制面板”;2、在“控制面板”界面中,点击“程序和功能”;3、在新界面中,找到并双击火狐浏览器图标;4、在卸载弹窗中,点击“下一步”;5、点击“卸载”即可。

被动检查对于被动健康检查,nginx和nginxplus会在事件发生时对其进行监控,并尝试恢复失败的连接。如果仍然无法恢复正常,nginx开源版和nginxplus会将服务器标记为不可用,并暂时停止向其发送请求,直到它再次标记为活动状态。上游服务器标记为不可用的条件是为每个上游服务器定义的,其中包含块中server指令的参数upstream:fail_timeout-设置服务器标记为不可用时必须进行多次失败尝试的时间,以及服务器标记为不可用的时间(默认为10秒)。max_fails-设置在fai


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

SublimeText3 Linux新版
SublimeText3 Linux最新版

EditPlus 中文破解版
體積小,語法高亮,不支援程式碼提示功能

SublimeText3漢化版
中文版,非常好用

記事本++7.3.1
好用且免費的程式碼編輯器

Dreamweaver Mac版
視覺化網頁開發工具