【发布时间】:2014-02-10 05:20:24
【问题描述】:
我已经使用 XMLHttprequest 实现了长轮询机制。我的问题是浏览器关闭后,服务器端进程继续运行,并没有关闭。
网络服务器是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 脚本(apache 有“php_value output_buffering Off”):
<?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 秒重复一次请求。
【问题讨论】:
-
你目前的代码是什么?
-
我添加了代码,发现php必须尝试将数据输出回客户端才能发现连接已中止
-
我完成了问题的最终描述
标签: php apache xmlhttprequest