Ajax彗星-缓慢打开下一个链接


Ajax comet - slow open next link

我对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();

Seteps:

  1. 打开页面并执行javascript,因此存在对backend.php的请求
  2. 监视日志文件-每1秒有一个新行
  3. 按下页面上的链接/菜单,浏览器开始加载下一页。在控制台(firebug或chrome控制台)中,我看到ajax请求被中止
  4. 监视日志文件-每隔1秒就会有新行,这样服务器上的连接就不会中止
  5. 打开http://localhost/server-status我可以看到状态为"W"的工作人员正在发送回复
  6. 等待一段时间(每次不同,但在大多数情况下大约30-60秒)连接关闭,因此在日志文件中我看到中止消息
  7. 加载下一页

我在每秒钟和刷新页面浏览器时创建了一个非常简单的案例-后端返回时间():-等待大约30-60秒,直到我在日志文件中看到中止消息或-realod页面,但在日志文件中没有中止。每个relod都会添加新的工作人员http://localhost/server-status日志文件中添加的行与worker相同。

我在CentOS 5.5服务器上尝试了一下,结果是一样的。我使用defautl apache配置(只添加一些虚拟主机并启用服务器状态)。

我认为配置有问题,但我不明白在哪里。你能帮我解决这个问题吗。

更新:我使用netstat来检查发生了什么。当请求处于活动状态时,netstat输出为:

tcp        0      0 127.0.0.1:35518         127.0.0.1:80            ESTABLISHED 2660/firefox     off (0.00/0/0)

CCD_ 1后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秒。这可能是操作系统配置的问题。

这里有两个问题:

第一:下一页加载缓慢-这是因为在每一页中我都使用session_start()。如果我在backend.php中启动会话,会话将在脚本完成后关闭并保存(因为我从不编写并关闭它)。这就是下一页打开速度太慢的原因(下一页也使用session_start())。为了解决这个问题,我从backend.php中删除了session_start(),但如果添加"session_write_close()",它也必须解决这个问题。

第二:backend.php不停止执行-这是因为我使用mod_php和php无法检测到浏览器断开连接/关闭。要检测浏览器断开连接,php脚本必须发送一些输出。在backedn.php中,我添加了要在每个while循环上执行的echo '0'; flush(); ob_flush();。因此,backend.php将在每个周期输出"0",它将检测浏览器何时断开连接(打开其他页面或按下停止按钮)或关闭,并停止执行。在客户端,我替换了.replace(/^0*/, '');,所以我删除了所有不必要的输出。

这解决了问题——现在,当浏览器试图打开其他页面,并且下一个页面(在此服务器上)按时打开时,后端脚本会停止执行。

我也遇到了同样的问题,但当页面像一样加载时,我在10秒钟后调用了我的comet ajax函数

$(function(){
  setTimeout('updateFeed()',10000);
});

它的工作原理就像一个魅力