【发布时间】:2012-03-02 06:26:06
【问题描述】:
我在使用 ajax comet 时遇到问题 - 页面加载后一切正常,但是当我尝试在同一主机上打开其他页面(某些菜单或链接)时,此页面在很长时间后加载(非常慢)。
服务器是 Slackware 13.37 Apache/2.2.20 PHP 5.3.8,脚本是 backend.php:
<?php
function my_abort_handler( ) {
write2file(connection_status() . ' SD Aborted!!!');
}
register_shutdown_function('my_abort_handler');
try {
error_reporting(0);
session_start();
if (!isUserLogedIn()) {
$return['message'] = "Login required";
$return['error'] = true;
echo json_encode($return);
exit();
}
if (empty($_SESSION['return'])) {
$_SESSION['return'] = false;
}
connectToDB();
while (!connection_aborted()) {
write2file(connection_status() . ' SD Aborted!!!');
$return = collectDataFromDB();
$d1 = array_diff_assoc($return, $_SESSION['return']);
$d2 = array_diff_assoc($return, $_SESSION['return']);
if ((!empty($d1)) || (!empty($d2))) {
$_SESSION['vote_return'] = $return;
echo json_encode($return);
flush();
ob_flush();
exit();
}
sleep(1);
}
} catch (Exception $e) {
$return['message'] = $e->getMessage();
$return['error'] = true;
echo json_encode($return);
}
在客户端:
var xhReq = false;
function runComet() {
xhReq = GetXmlHttpObject();
xhReq.open("GET",'backend.php',true);
xhReq.onreadystatechange=consoleinfo;
xhReq.send(null);
}
function consoleinfo() {
if (xhReq.readyState == 4) {
if (xhReq.status == 200) {
console.info(xhReq.responseText);
} else {
console.info("Error Status:" + xhReq.status);
}
runComet();
}
runComet();
设置:
- 打开页面并执行javascript,所以有请求到backend.php
- 监控日志文件 - 每 1 秒有一个新行
- 点击页面上的链接/菜单,浏览器开始加载下一页。在控制台(firebug 或 chrome 控制台)中,我看到 ajax 请求已中止。
- 监控日志文件 - 每 1 秒有一个新行,因此服务器上的连接不会中止。
- 打开http://localhost/server-status,我可以看到状态为“W”的工作人员正在发送回复。
- 等待一段时间(每次都不同,但在大多数情况下大约 30 到 60 秒)连接关闭,因此在日志文件中我会看到中止消息。
- 下一页已加载
我创建了一个非常简单的案例——每秒钟的后端返回时间()。并刷新页面浏览器: - 等待大约 30 - 60 秒,直到我在日志文件中看到中止消息 或者 -realod 页面,但在日志文件中没有中止。每个 relod 在http://localhost/server-status 中添加新的worker,并且在日志文件中添加的行与workers 相同。
我在 CentOS 5.5 服务器上尝试了这个,结果是一样的。我使用默认的 apache 配置(只添加一些虚拟主机并启用服务器状态)。
我认为配置有问题,但我不明白在哪里。你能帮我解决这个问题吗?
更新: 我使用 netstat 检查发生了什么。当请求处于活动状态时,netstat 输出为:
tcp 0 0 127.0.0.1:35518 127.0.0.1:80 ESTABLISHED 2660/firefox off (0.00/0/0)
xhReq.abort() 之后的 netstat 输出为:
tcp 1 0 127.0.0.1:80 127.0.0.1:35518 CLOSE_WAIT 3174/httpd keepalive (7167.02/0/0)
所以在这种情况下,连接将保持活动状态 7167 秒,后台脚本将工作 7167 秒。这可能与操作系统配置有关。
【问题讨论】: