阿贾克斯彗星 - 慢速打开下一个链接

时间:2012-03-02 06:26:06

标签: php ajax apache comet

我遇到ajax彗星的问题 - 页面加载后一切都工作很好但是当我尝试在同一主机(某些菜单或链接)上打开其他页面时,此页面会在很长一段时间后加载(非常慢)。 / p>

服务器是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. 下一页已加载
  8. 我创造了非常简单的案例 - 后端返回时间()每秒。并刷新页面浏览器: - 等待大约30 - 60秒,直到我在日志文件中看到中止消息 要么 -realod页面但在日志文件中没有中止。每个relod都在http://localhost/server-status中添加新worker,在日志文件中添加的行与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)
    

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

2 个答案:

答案 0 :(得分:0)

这里的问题有两个:

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

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

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

答案 1 :(得分:0)

我遇到了同样的问题,但是当页面加载时,我在10秒后调用了我的彗星ajax函数

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

它就像一个魅力