weixin_33726313 2012-03-02 06:26 采纳率: 0%
浏览 32

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

I have a problem with ajax comet - after the page is loaded everything works greate but when I try to open other page on the same host (some menu or link) this page is loaded after long time (very slow).

Server is Slackware 13.37 Apache/2.2.20 PHP 5.3.8 and script is 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);
}

On the client:

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. Open page and javascript is executed, so there is request to backend.php
  2. Monitor the log file - every 1 sec there is new row
  3. Press on the link/menu on the page and browser start to load next page. In the console (firebug or chrome console) I see the ajax request is aborted.
  4. Monitor the log file - every 1 sec there is new row so the connection on the server is not aborted.
  5. Open http://localhost/server-status and I can see the worker in status "W" Sending Reply.
  6. Wait some time (every time it different but in most cases around 30 - 60 secs) connection is closed so in the log file I see the abort message.
  7. Next page is loaded

I create very simple case - backend return time() on every sec. and on refresh of the page browser: -waits around 30 - 60 sec until I see abort message in the log file or -realod the page but in the log file there is no abort. Every relod add new worker in http://localhost/server-status and rows added in log file are the same as the workers.

I try this on CentOS 5.5 server and the result was the same. I use the defautl apache configuration (only add some virtual hosts and enable server-status).

I think there is a problem with configurion but I can not understand where. Can you help me to solve this problem.

UPDATE: I use netstat to check what's happening. When the request is active netstat output is:

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

and after xhReq.abort() netstat output is:

tcp        1      0 127.0.0.1:80            127.0.0.1:35518         CLOSE_WAIT  3174/httpd       keepalive (7167.02/0/0)

so in this case the connection will be keepalive for 7167 secs and background script will work 7167 secs. May be this is something with the OS configuration.

  • 写回答

2条回答 默认 最新

  • ~Onlooker 2012-12-01 22:22
    关注

    Problems here are two:

    First: slow load of the next page - this is because in every page I use session_start(). If I start session in backend.php the session will be closed and saved after script finish (because I never write and close it). This is the reason next page is opened so slow (next page also use session_start()). To fix this problem I remove session_start() from backend.php but if you add 'session_write_close()' it must solve the problem too.

    Second: backend.php does not stop execution - this is because I use mod_php and php can not detect browser disconnectct/close. To detect browser disconnect php script must send some output. In backedn.php I add echo '0'; flush(); ob_flush(); to be executed on every while cycle. So backend.php will output '0' on every cycle and it will detect when browser was disconnected (open other page or stop button was pressed) or closed and it's execution will stop. On the client side I replace .replace(/^0*/, ''); so I remove all unnecessary output.

    This solve the problem - now backend script stops it's execution when browser try to open other page and next page (on this server) opens on time.

    评论

报告相同问题?

悬赏问题

  • ¥20 matlab计算中误差
  • ¥15 对于相关问题的求解与代码
  • ¥15 ubuntu子系统密码忘记
  • ¥15 信号傅里叶变换在matlab上遇到的小问题请求帮助
  • ¥15 保护模式-系统加载-段寄存器
  • ¥15 电脑桌面设定一个区域禁止鼠标操作
  • ¥15 求NPF226060磁芯的详细资料
  • ¥15 使用R语言marginaleffects包进行边际效应图绘制
  • ¥20 usb设备兼容性问题
  • ¥15 错误(10048): “调用exui内部功能”库命令的参数“参数4”不能接受空数据。怎么解决啊