1
我實現了長輪詢機制使用XMLHttprequest。我的問題是,瀏覽器關閉後,服務器端進程繼續運行,不關閉。XmlHttpRequest不終止請求處理
該web服務器是httpd apache並且該過程是一個php腳本。
我確實希望PHP腳本在瀏覽器關閉後關閉。
我發現PHP不會發現連接關閉,除非它試圖將數據輸出回瀏覽器。 這是一個問題,因爲它會損害最小化帶寬使用的目標。
客戶端腳本使用onreadystatechange嘗試讀取部分數據,而不需要爲每個通信添加新的XMLHttpRequest。 一些瀏覽器將不會允許讀取部分數據,直到整個反應結束:
<!DOCTYPE html>
<html>
<head>
<meta content="text/html; charset=utf-8" http-equiv="Content-Type"></meta>
<script type="text/javascript" src="jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(NewReq);
var mode = 0;
function NewReq() {
var Req = new XMLHttpRequest();
var url = 'a.php';
if (mode) {
url += '?mode=' + mode;
}
Req.open('GET', url);
Req.onreadystatechange = function(event) {
var handler = ReadyState[this.readyState];
if (typeof handler == 'function') {
handler(this);
}
};
inc_mycookie();
Req.send();
}
var ReadyState = [
//'NotInit', 'ReqRec', 'ConEst'
null , null, null,
partial // 'Proccessing'
,
complete //'Finishied'
];
function partial(Req) { //'Proc'
if (mode == 1) {
return;
}
try {
var strings = Req.response.split(';');
strings.pop();
var data = JSON.parse(strings.pop());
$('#message').text(data);
mode = 2;
}
catch (e) {
$('#message').text(e.message);
mode = 1;
}
return;
}
function complete(Req) {
var last = $('#message').text();
$('#output').text(last);
NewReq();
}
function inc_mycookie() {
var matches = document.cookie.match(/(?:^|;)mine=([^;]+);?/);
if (matches) {
var inc = parseInt(matches[1]) + 1;
document.cookie = 'mine=' + inc;
}
}
</script>
</head>
<body>
<h3> output </h3>
<div id="output"></div>
<h3> partial </h3>
<div id="message"></div>
</body>
</html>
,這裏是PHP腳本(阿帕奇有「php_value output_buffering關」):
<?php
header('Content-type: application/json');
if (!isset($_COOKIE['mine'])) {
setcookie('mine', 23);
$_COOKIE['mine'] = 23;
}
$mode = isset($_GET['mode']) ? $_GET['mode'] : 1;
print json_encode('test_' . $_COOKIE['mine']) . ';';
if ($mode == 2) {
$iter = 8;
while($iter) {
sleep(2);
$iter--;
error_log('a.php:' . $iter);
// if i remove this line, then erro_log will continue to show even when browser is closed
print json_encode('test_' . $_COOKIE['mine'] . '_' . $iter) . ';';
}
}
?>
的情況下
在瀏覽器支持部分響應的情況下,損害並不算太壞。
但如果瀏覽器要求整個響應完成,那麼損害將是長輪詢的完全折中,意味着每5秒發出一次重複請求。
什麼是你到目前爲止的代碼? – everton
我添加了代碼,發現php必須嘗試將數據輸出回客戶端以發現連接已被中止 –
我完成了問題的最終描述 –