2011-07-31 1 views
0

여기 내 문제가 있습니다.스크립트 백엔드 실행을 기반으로 진행률 표시 줄을 표시하도록 AJAX 인터페이스를 설계하는 방법

  1. I는 입력 X에 기초하여 XML 출력 파일을
  2. I 호출 다른 파일을 상기 (1) (ⅰ 많은 의미) X에 대한 상이한 수와 회 10000 파일

사용자가 "이동"을 클릭하면 10000 개의 X를 모두 통과해야하며 동시에 수행 된 작업의 진행 상황을 보여야합니다. (헴은 10 초에 한 번 업데이트 될 수 있습니다).

어떻게해야합니까? 나는 아이디어가 필요해. 나는 AJAX와 물건에 대한 방법을 안다. 그러나 나의 프로그램이 취해야하는 구조는 무엇인가?

편집

그래서 난 아래의 대답에 따라 세션 변수에 내 출력을 저장했다. 그런 다음 대답을 출력합니다. 무슨 일이 일어나고 :

나는 loong 스크립트를 실행할 때. 1 분 안에 말을 실행합니다. 하지만 내 말은 (새 창에서) 내 SESSION 변수를 출력하는 파일을 열면 첫 번째 스크립트가 실행됩니다. 어느 것이 내가 원하는 것과 완전히 반대입니다. 뭐가 문제 야? 그것은 내 syste/서버가 여러 요청을 처리하거나 무엇입니까?

편집 2

내가 파일 접근 방식 사용 : 내가 원하는 것을 읽으려면 을 기능이 있습니다

> <?php include_once '../includeTop.php'; echo 
> util::readFromLog("../../Files/progressData.tmp"); ?> 

및 다른 스크립트

$processed ++; 
util::writeToLog($dir.'/progressData.tmp', "Files processed: $processed"); 

에서

:

public static function writeToLog($file,$data) { 
     $f = fopen($file,"w"); 
     fwrite($f, $data); 
     fclose($f); 
    } 
    public static function readFromLog($file) { 
     return file_get_contents($file); 
    } 

하지만 여전히 동일한 문제가 지속됩니다. 나는 수작업으로 1, 2, 3 등으로 업데이트 된 gettin 파일을 볼 수있다. 그러나 php로 스크립트를 실행하면 원래 스크립트가 출력 될 때까지 기다린다.

EDIT 3

확인 마침내 해결책을 발견 하였다. php 파일에서 출력을 찾는 대신 지금 로그를 직접 이동하여 찾으십시오.

답변

1

편집 : 제가 $_SESSION에 대해 잘못되었습니다. 비동기 적으로 업데이트되지 않습니다. 즉, 스크립트에 저장 한 값은 스크립트가 끝날 때까지 액세스 할 수 없습니다. 오케이.

그래서 진행 상황을 비동기식으로 업데이트해야합니다 (예 : pyroscope에서 제안하는 것처럼, 여전히 최상의 솔루션입니다). 파일 또는 데이터베이스.

즉, 값을 저장하는 데 $_SESSION을 사용하는 대신 memcached, 파일 또는 데이터베이스에 값을 저장해야합니다.

e.e. 데이터베이스

$progress = 0; 
mysql_query("INSERT INTO `progress` (`id`, `progress`) VALUES ($uid, $progress)"); 
# loop starts 
    # processing... 
    $progress += $some_increment; 
    mysql_query("UPDATE `progress` SET `progress`=$progress WHERE `id`=$uid"); 
# loop ends 

를 사용하거나 파일

$progress = 0; 
file_put_contents("/path/to/progress_files/$uid", $progress); 
# loop starts 
    # processing... 
    $progress += $some_increment; 
    file_put_contents("/path/to/progress_files/$uid", $progress); 
# loop ends 

를 사용하여 그리고 아약스를 통해 진행 상황을 요청할 때 다음, 데이터베이스에서 선택한 파일을 읽기 /. 하지만 그것은 memcached에 비해 꽤 좋은 해결책은 아닙니다.

또한 파일/데이터베이스 행이 모두 완료되면이를 제거해야합니다.


당신은 $_SESSION 변수의 진행 상황을 넣을 수는 (당신은 그것을 고유 한 이름이 필요합니다), 프로세스가 실행되는 동안 업데이트합니다. 한편 아약스 요청은 단순히 그 다음이 아약스를 통해 요청 때 단순히 $_SESSION[$uid] 값을 뱉어 URL을 가지고 특정 간격

function heavy_process($input, $uid) { 
    $_SESSION[$uid] = 0; 
    # loop begins 
     # processing... 
     $_SESSION[$uid] += $some_increment; 
    # loop ends 
} 

에서 그 변수를 가져옵니다. 그런 다음 반환 된 값을 사용하여 진행률 막대를 업데이트합니다. $ UID

편집을 만들 sha1(microtime()) 같은 것을 사용 pyroscope의 솔루션이 기술적으로 더 나은,하지만 당신은 memcached를 또는 백그라운드 프로세스를 실행할 수있는 능력을 가진 서버가없는 경우, 당신은 $_SESSION 대신

+0

안녕을 사용할 수 있습니다 ,이 코드를 사용하여 시도하고 오류가 발생했습니다. 나는 그 질문에서 그것을 업데이트 할 것이다. 똑같이 들여다보십시오. – footy

+0

@footy : 느린 스크립트가 완료 될 때까지 서버가 진행 요청에 전혀 응답하지 않습니까? 아니면 즉시 응답하지만 잘못된 값으로 응답합니까? – Flambino

+0

@footy : 내 대답을 업데이트했습니다. – Flambino

3

백그라운드 작업에서 직접 memcached로 진행률을 입력 한 다음 (자바 스크립트 응용 프로그램에서 요청한 경우 해당 값을 전달합니다 (도달하지 않은 한 타이머에 의해 트리거 됨) 100 %). 알아야 할 것은 "트랜잭션 ID"를 백그라운드 작업과 자바 스크립트 측면 모두에 전달하는 방법뿐입니다. 따라서 memcached에서 동일한 키에 액세스합니다.

관련 문제