2012-03-02 5 views
0

У меня проблема с ajax комета - после загрузки страницы все работает greate, но когда я пытаюсь открыть другую страницу на том же хосте (какое-то меню или ссылку), эта страница загружается после долгого время (очень медленное).Ajax комета - медленная открытая следующая ссылка

Сервер 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 console) я вижу, что запрос ajax прерван.
  4. Мониторинг файла журнала - каждые 1 секунду появляется новая строка, поэтому соединение с сервером не прерывается.
  5. Открыть http://localhost/server-status и увидеть рабочего в статусе «W» Отправка ответа.
  6. Подождите некоторое время (каждый раз, когда он отличается, но в большинстве случаев около 30-60 секунд) соединение закрывается, поэтому в файле журнала я вижу сообщение об ошибке.
  7. Следующая страница загружается

создать очень простой случай - бэкэнд время возврата() на каждом сек. и при обновлении браузера страниц: - ждет около 30-60 секунд, пока не увижу сообщение о прерывании в файле журнала или -realod на странице, но в файле журнала нет прерывания. Каждый relod добавляет нового работника в http://localhost/server-status, а строки, добавленные в файл журнала, совпадают с рабочими.

Я пробовал это на сервере CentOS 5.5, и результат был тот же. Я использую конфигурацию defautl apache (добавьте только виртуальные хосты и включите статус сервера).

Я думаю, что есть проблема с конфигурацией, но я не могу понять, где. Можете ли вы помочь мне решить эту проблему.

UPDATE: Я использую 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) 

так что в этом случае соединение будет KeepAlive на 7167 секунд и фоновый скрипт будет работать 7167 секунд. Может быть, это что-то с конфигурацией ОС.

ответ

0

Проблемы здесь две:

Первое: медленная загрузка на следующей странице - это потому, что на каждой странице я использую session_start(). Если я запустил сеанс в backend.php, сеанс будет закрыт и сохранен после завершения скрипта (потому что я никогда не пишу и не закрываю его).Это причина, по которой следующая страница открывается настолько медленно (на следующей странице также используется session_start()). Чтобы устранить эту проблему, я удаляю session_start() из backend.php, но если вы добавите «session_write_close()», это также должно решить проблему.

Second: backend.php не останавливает выполнение - это потому, что я использую mod_php, и php не может обнаружить браузер disconnectct/close. Для обнаружения браузера отключить php-скрипт должен отправить некоторый вывод. В backedn.php я добавляю echo '0'; flush(); ob_flush(); для выполнения каждого цикла. Таким образом, backend.php будет выводить «0» на каждый цикл, и он обнаружит, когда браузер был отключен (открыта другая страница или нажата кнопка остановки) или закрыт, и его выполнение остановится. На стороне клиента я заменяю .replace(/^0*/, '');, поэтому я удаляю все ненужные данные.

Это решение проблемы - теперь скрипт backend останавливает выполнение, когда браузер пытается открыть другую страницу и следующую страницу (на этом сервере) открывается вовремя.

0

У меня была та же проблема, но я назвал свою функцию комета АЯКС через 10 секунд при загрузке страницы, как

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

и он работает как шарм