【问题标题】:Ajax comet - slow open next linkAjax 彗星 - 缓慢打开下一个链接
【发布时间】: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();

设置:

  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,并且在日志文件中添加的行与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 秒。这可能与操作系统配置有关。

【问题讨论】:

    标签: php ajax apache comet


    【解决方案1】:

    这里有两个问题:

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

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

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

    【讨论】:

      【解决方案2】:

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

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

      它就像一个魅力

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-07-12
        • 2011-06-10
        • 1970-01-01
        • 2011-06-10
        • 1970-01-01
        • 2015-03-22
        • 2021-05-31
        • 1970-01-01
        相关资源
        最近更新 更多