PHP Conference Japan 2024

connection_aborted

(PHP 4, PHP 5, PHP 7, PHP 8)

connection_aborted檢查客戶端是否已斷線

說明

connection_aborted(): int

檢查客戶端是否已斷線。

參數

此函式沒有參數。

傳回值

如果客戶端已斷線,則傳回 1,否則傳回 0。

參見

新增註釋

使用者貢獻的註釋 2 則註釋

nathanb at php dot net
11 年前
一個檢測連線是否關閉的小技巧,無需發送可能會損壞資料流(例如二進位檔案)的資料,您可以結合使用 HTTP/1.1 的分塊傳輸,方法是發送「0」(「零」)作為前導區塊大小,而無需其他任何內容。

*注意* 重要的是要注意,不要每隔幾秒就檢查一次資料流。這樣做可能會增加傳送給使用者的資料量,而使用者卻沒有任何收益。

這樣做的理由是,如果您正在產生一份需要很長時間才能執行且佔用大量伺服器資源的報告。這將允許伺服器檢測使用者是否取消了下載,並在不損壞正在下載的檔案的情況下執行任何清理工作。

以下是一個範例

<?php
ignore_user_abort
(true);
header('Transfer-Encoding:chunked');
ob_flush();
flush();
$start = microtime(true);
$i = 0;
// 使用此函式將任何內容輸出到瀏覽器。
function vPrint($data){
if(
strlen($data))
echo
dechex(strlen($data)), "\r\n", $data, "\r\n";
ob_flush();
flush();
}
// 完成資料流傳輸到瀏覽器後,您*必須*執行此函式。
function endPacket(){
echo
"0\r\n\r\n";
ob_flush();
flush();
}
do{
echo
"0";
ob_flush();
flush();
if(
connection_aborted()){
// 當連線關閉時會發生這種情況
file_put_contents('/tmp/test.tmp', sprintf("連線已關閉\n連線開啟時間: %01.5f 秒\n迴圈迭代次數: %s\n\n", microtime(true) - $start, $i), FILE_APPEND);
endPacket();
exit;
}
usleep(50000);
vPrint("我每次迭代(每 0.5 秒)都會被輸出<br />\n");
}while(
$i++ < 200);
endPacket();
?>
Rupak Bajgain
1 年前
我使用的一個技巧是透過在註解中傳送值來實現具有斷線檢查機制的长轮询。

例如,對於 JSON 格式:
在連線中止前傳送 0 並清空緩衝區。
例如: {"x":"000000
在結果準備好後,傳送 ", 和移除第一個 { 之後的 JSON 資料。
所以看起來像這樣:
{"x":"00000000000","y":"result","z":"result2"}
To Top