2012-03-02 3 views
0

아약스 혜성에 문제가 있습니다. 페이지가로드 된 후 모든 것이 greate로 작동하지만 같은 호스트 (일부 메뉴 또는 링크)에서 다른 페이지를 열려고하면이 페이지가 오래로드됩니다. 시간 (매우 느림).Ajax 혜성 - 천천히 다음 링크를 엽니 다.

서버/2.2.20 PHP 5.3.8 아파치 슬랙웨어 13.37이며, 스크립트 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. 열린 페이지와 자바 스크립트가 실행되었으므로 backend.php에 대한 요청이 있습니다.
  2. 로그 파일 모니터링 - 1 초마다 새로운 행이 있습니다.
  3. 페이지의 링크/메뉴를 누르면 브라우저가 시작되어 다음 페이지를로드합니다. 콘솔 (방화 광 또는 크롬 콘솔)에서 아약스 요청이 중단 된 것을 봅니다.
  4. 로그 파일을 모니터링하십시오. 1 초마다 새 행이 있으므로 서버의 연결이 중단되지 않습니다.
  5. http://localhost/server-status을 열면 상태가 "W"인 회신을 볼 수 있습니다.
  6. 잠시 기다리십시오 (때마다 다르지만 대부분의 경우 30-60 초 정도) 연결이 닫혀 있으므로 로그 파일에 중단 메시지가 표시됩니다.
  7. 다음 페이지가

을로드 난 아주 간단한 경우를 생성 - 모든 초에 백엔드 반환 시간을(). 그리고 페이지 브라우저를 새로 고침 할 때 : 또는 - 로그 파일에서 메시지를 중단하지만 로그 파일에서 중단이 표시 될 때까지 약 30 - 60 초 정도 대기합니다 ( ). 모든 relod는 http://localhost/server-status에 새 작업자를 추가하고 로그 파일에 추가 된 행은 작업자와 같습니다.

CentOS 5.5 서버에서이 작업을 시도했지만 그 결과는 동일했습니다. 난 defautl 아파치 구성 (일부 가상 호스트를 추가하고 서버 상태를 사용)를 사용합니다.

내가 configurion에 문제가 있다고 생각하지만 어디서 이해할 수 없습니다. 이 문제를 해결하도록 도와 주시겠습니까?

업데이트 : 나는 무슨 일이 일어나는지 확인하기 위해 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 초를 작동합니다. 이것은 OS 구성의 일부일 수 있습니다. 여기

답변

0

문제는 두 가지 :

첫째 : 다음 페이지의 느린로드 - 모든 페이지에 내가 session_start()을 사용하기 때문이다. backend.php에서 세션을 시작하면 세션이 닫히고 스크립트 작성이 끝난 후 저장됩니다 (쓰기 및 닫기를하지 않기 때문에).이것은 다음 페이지가 너무 느리게 열리는 이유입니다 (다음 페이지에서도 session_start() 사용). 이 문제를 해결하려면 backend.php에서 session_start()을 제거하십시오.하지만 'session_write_close()'를 추가하면 문제도 해결되어야합니다.

두번째 : backend.php는 실행을 멈추지 않습니다 - 이것은 mod_php를 사용하고 PHP는 브라우저 disconnectct/close를 감지 할 수 없기 때문입니다. 브라우저 연결 해제 PHP 스크립트를 감지하려면 일부 출력을 보내야합니다. backedn.php에서는주기마다 매번 실행될 echo '0'; flush(); ob_flush();을 추가합니다. 그래서 backend.php는 매주기마다 '0'을 출력 할 것이고 브라우저가 연결이 끊어 졌을 때 (다른 페이지를 열거 나 멈춤 버튼을 눌렀을 때) 감지하거나 닫을 것이고 실행이 멈출 것입니다. 클라이언트 측에서는 .replace(/^0*/, '');을 대체하므로 불필요한 출력을 모두 제거합니다.

이 문제가 해결되었습니다. 이제 브라우저가 다른 페이지를 열려고 시도 할 때 백엔드 스크립트가 실행을 중지하고이 서버의 다음 페이지가 정시에 열립니다.

0

저도 같은 문제가되었지만 그것이 마치 마법처럼 페이지

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

같은 부하와 작동 할 때 나는 10 초 후에 내 혜성 아약스 함수를 호출

관련 문제