2011-07-27 5 views
0

시간이 많이 걸리는 많은 기능이있는 페이지가 있습니다. 내가하고 싶은 것은 프로세스의 각 단계가 완료되면 웹 페이지를 업데이트하여 사용자에게 어떤 단계가 완료되었는지 알려주는 것입니다. 본질적으로 사용자가 쿼리를 제출하면 서버는 데이터베이스를 쿼리하고 데이터를 처리하며 이미지를 그리고 페이지에 결과를 표시합니다. 웹 페이지에서 기능이 어떤 단계인지 말하고 싶습니다. 그것은 "Querying"다음 "Processing"...이라고 말할 것입니다.웹 페이지를 프로세스로 업데이트하십시오.

의사는 :

protected void Search(object sender, EventArgs e){ 

    //display that the process has begun 
    List queryResults = Query() 
    //display that the query is finished 
    foreach(item in queryResults){ 
     ProcessItem(item) 
     //display that item has been processed 
     Render(item) 
     //display item has been rendered 
    } 

} 

나는 그것을 다시로드하지 않고 페이지를 업데이트하기 위해 Ajax를 사용으로 보았다,하지만 내 간단한 이해 (아약스와 제로 경험)에서 클라이언트는 서버에서 파일을 요청하는 것입니다. Ajax는 내가 필요한 도구입니까? 그렇다면 주석 영역에서 클라이언트에게 아약스 응답을 보냅니다.

답변

0

웹 서버는 요청되지 않은 데이터를 클라이언트로 보낼 수 없습니다. 이들은 요청 - 응답주기를 준수합니다. 다른 방법은 메시지 큐를 사용하여 복잡성이 크게 증가하는 것입니다.

클라이언트의 폴링은 그렇게 나쁘지 않습니다. 웹 서버는 많은 짧은 요청을 처리하는 데 능숙하며 2 또는 3 초의 폴링 간격은 충분히 빠릅니다.

다음은 내가 사용하는 폴링 방법입니다. 그것은 비동기 다시 폴링하기 전에 올 응답을 기다립니다 (jQuery를 필요) :

function poll(url, task, progressBar, resultsCallback, 
     timeoutMillis, pollIntervalMillis) { 
    $.ajax({ 
     url: url, 
     type: 'GET', 
     dataType: 'json', 
     timeout: timeoutMillis, 
     data: 'action=poll&task='+task, 
     success: (function(response, status, xhr) { 
      if ('progress' in response) { 

       // update the UI with the progress 
       progressBar.setValue(response.progress); 
      } 
      if ('status' in response) { 
       if (response.status == 'pending') { 

        // task is not finished, continue polling 
        setTimeout((function() { 
         poll(url, task, progressBar, resultsCallback, 
           timeoutMillis, pollIntervalMillis); 
        }), pollIntervalMillis); 
       } 
       else { 

        // task completed 
        if (response.status == 'cancelled') { 
         progressBar.setColor('red'); 
         progressBar.setText("Task '"+task+"' was cancelled"); 
        } 
        else { 
         progressBar.setColor('green'); 
         progressBar.setText("Task '"+task+"' complete"); 
        } 

        // GET the results 
        $.ajax({ 
         url: url, 
         type: 'GET', 
         timeout: timeoutMillis, 
         data: 'action=results&task='+task, 
         success: (function(response, status, xhr) { 
          resultsCallback(response, status, xhr); 
         }), 
         error: error 
        }); 
       } 
      } 
     }), 
     error: error 
    }); 

    function error(xhr, status, err) { 
     alert('Failure to communicate with server: ' + status + ', ' + err); 
    } 
} 

그리고 서버 측 코드는 다음과 같이 함께 여론 조사에 응답해야합니다

{"progress" : 42, "status" : "pending"} 
0

AJAX로 작업 한 경우 클라이언트가 자바 스크립트를 실행하여 빈 상태에서 ajax 요청을 실행하여 상태가 업데이트되었는지 여부를 확인해야합니다. 다른 옵션은 클라이언트에서 실버 라이트를 사용하고 있으며,보다 강력한 이벤트 기반 대화를 수행 할 수 있습니다.

둘 다 실행 가능한 옵션입니다. http://www.silverlight.net/learn/advanced-techniques/wcf-ria-services/get-started-with-wcf-ria-services

+0

것은 당신이 정교한 또는 이것에 대한 좋은 소식을 알려주시겠습니까? 차라리 클라이언트가 서버를 핑 (ping)하여 단계가 완료되었는지 묻지 않을 것입니다. 차라리 서버가 각 단계의 끝에서 클라이언트에게 메시지를 보내도록하고 싶습니다. – spots

+0

@spots 편집에서 –

0

일정한 간격으로 아약스 요청 폴링이 가장 일반적인 옵션 또는 HTTP 응답의 버퍼링을 끄고 상태가 다시 업데이트 스트림 수 :

여기에 실버 + WCF에 대한 일반적인 시작하는 공간입니다 하나의 http 요청 내에서 모두 클라이언트로 전송됩니다. 장기 실행 작업 인 경우 후자의 시나리오에서 신중하게 사용자 경험과 확장 성을 고려해야합니다.

HTML 5 웹 소켓은이 특정 시나리오도 해결합니다. 그러나 현재 상태가 Html 5 호환 브라우저에서 어떤 상태인지 확실하지 않습니다.

+0

서버의 오픈 소켓은 웹 브라우저와 네트워크/프록시/방화벽 종류를 고려한 클라이언트 측 제한 시간 규칙을 보장하지 않습니다. –

관련 문제