2009-07-10 4 views
14

서버에서 클라이언트 요청 웹 페이지. Clent는 추가 계산을 요청합니다. 서버는 일련의 계산을 수행하고 사용 가능한 즉시 부분 결과를 보냅니다 (텍스트 형식, 각 행에는 별도의 전체 항목이 들어 있음). 클라이언트는 서버가 제공 한 정보를 사용하여 웹 페이지 (JavaScript 및 DOM 포함)를 업데이트합니다."HTTP 스트리밍"(푸시) AJAX 패턴의 교차 브라우저 구현

이것은 Ajaxpatterns 사이트의 HTTP Streaming (current 버전) 패턴에 적합합니다.

질문은 크로스 브라우저 (브라우저 불가지론) 방식으로, JavaScript 프레임 워크를 사용하지 않거나 jQuery와 같은 간단한 프레임 워크를 사용하지 않는 것이 좋습니다.

문제는 크로스 브라우저 방식으로 XMLHttpRequest를 생성하는 것으로 시작되지만 주 항목은 모든 브라우저가 올바르게 구현되지 않는다고 생각합니다. onreadystatechange에서 XMLHttpRequest까지; 모든 브라우저가 각 서버의 onreadystatechange 이벤트를 호출하지는 않습니다. (펄의 CGI 스크립트 내에서 서버 플러시를 강제하는 방법). Ajax 패턴의 예제 코드는 timer를 사용하여이를 처리합니다. onreadystatechange에서 부분 응답을 감지하면 타이머 솔루션을 놓을까요?


추가 2009년 11월 8일

현재 솔루션 : 내가 사용한다면

function createRequestObject() { 
     var ro; 
     if (window.XMLHttpRequest) { 
       ro = new XMLHttpRequest(); 
     } else { 
       ro = new ActiveXObject("Microsoft.XMLHTTP"); 
     } 
     if (!ro) 
       debug("Couldn't start XMLHttpRequest object"); 
     return ro; 
} 

: 나는 XMLHttpRequest 객체를 생성하기 위해 다음과 같은 기능을 사용
jQuery와 같은 일부 (가볍고 가벼운) JavaScript 프레임 워크, 사용자가 jQuery를 설치하지 않도록 선택합니다.

다음 코드를 사용하여 AJAX를 시작합니다. 일부 브라우저는 서버가 연결을 종료 한 후 (단지 수십 초가 소요될 수 있음)에만 onreadystatechange을 호출하기 때문에 서버가 데이터를 플러시하는 즉시 (약 초마다 또는 더 자주) 호출하지 않기 때문에 setInterval이 사용됩니다.

function startProcess(dataUrl) { 
     http = createRequestObject(); 
     http.open('get', dataUrl); 
     http.onreadystatechange = handleResponse; 
     http.send(null); 

     pollTimer = setInterval(handleResponse, 1000); 
} 

handleResponse 기능은 가장 복잡한 일이지만, 그것의 스케치는 다음과 같습니다. 더 잘할 수 있습니까? 가벼운 JavaScript 프레임 워크 (예 : jQuery)를 사용하면 어떻게 될까요?

function handleResponse() { 
    if (http.readyState != 4 && http.readyState != 3) 
     return; 
    if (http.readyState == 3 && http.status != 200) 
     return; 
    if (http.readyState == 4 && http.status != 200) { 
     clearInterval(pollTimer); 
     inProgress = false; 
    } 
    // In konqueror http.responseText is sometimes null here... 
    if (http.responseText === null) 
     return; 

    while (prevDataLength != http.responseText.length) { 
     if (http.readyState == 4 && prevDataLength == http.responseText.length) 
      break; 
     prevDataLength = http.responseText.length; 
     var response = http.responseText.substring(nextLine); 
     var lines = response.split('\n'); 
     nextLine = nextLine + response.lastIndexOf('\n') + 1; 
     if (response[response.length-1] != '\n') 
      lines.pop(); 

     for (var i = 0; i < lines.length; i++) { 
      // ... 
     } 
    } 

    if (http.readyState == 4 && prevDataLength == http.responseText.length) 
     clearInterval(pollTimer); 

    inProgress = false; 
} 
+0

분명히 코드 예제를 답장으로 추가하고 올바른 것으로 표시해야합니다! –

+4

"사용자가 jQuery를 설치하지 않기로 결정한 경우"? – Basic

+0

안녕하세요, 방금 해결책을 찾았지만 요청이 아직 끝나지 않은 상태에서 responseText를 얻으려고 할 때 IE로는 작동하지 않을 것입니다. 그러면 다음과 같은 메시지가 나타납니다. 메시지 : "이 작업을 완료하는 데 필요한 데이터를 아직 사용할 수 없습니다." –

답변

2

링크 된 솔루션은 실제로 AJAX가 아닙니다. 그들은 그것을 HTTP 스트리밍이라고 부르지 만 근본적으로 단지 폴링입니다.

링크가있는 예에서는 방화 상자를 사용하여 쉽게 볼 수 있습니다. Net 패널을 켜십시오 - XHR 항목은 없지만 원래 페이지를로드하는 데 10 초 이상 걸립니다. 왜냐하면 HTML의 출력을 지연시키기 위해 PHP를 사용하기 때문입니다. 이것은 긴 폴링의 본질입니다. HTTP 연결은 열린 상태로 유지되고주기적인 HTML은 javascript 명령입니다.

당신이 jQuery를 예를의 setTimeout() 또는 setInterval을()

으로하지만, 클라이언트 측에서 완전히

<script type="text/javascript"> 
    $(document).ready(function() 
    { 
    var ajaxInterval = setInterval(function() 
    { 
     $.getJSON(
     'some/servie/url.ext' 
     , { sample: "data" } 
     , function(response) 
      { 
      $('#output').append(response.whatever);   
      } 
    ); 
    }, 10000); 
    }); 
</script> 
+0

나는 exaxtly 내가 원하는. 서버 계산은 일반 텍스트 형식으로 출력을 생성합니다. XHR을 사용하면 클라이언트 (플러시/타이머 onreadystatechange)에서이 응답을 직접받을 수 있으며 부분 데이터에 따라 웹 페이지를 편집 할 수 있습니다. –

+0

원하는 것은 무엇이 아닌가요? 긴 폴링? 나는 어느 쪽의 방법도 추천하지 않고있다 - 나는 단지 당신의 옵션이 무엇인지에 관해 당신에게 이야기하고있다. –

+0

롱 풀링 (Comet)을 사용하려는 경우, Apache가 그런 종류의 일을하도록 설계되지 않았기 때문에 Meteor 서버 소프트웨어 사용을 고려해야합니다. 그리고 거의 모든 것을 처리하는 자바 스크립트 라이브러리가 있습니다. 이름이 기억 나지 않아 나중에 게시 할 수 있습니다. – usoban

0

을 폴링을 수행하도록 선택할 수 있습니다 나는 궤도

을 살펴 것

그들은 구성과 브라우저 스니핑에 따라 선택하는 몇 가지 혜성 전송 구현을 사용합니다.

이렇게도 궤도에 대한 서버 측에서 봐,

http://orbited.org/svn/orbited/trunk/daemon/orbited/static/Orbited.js을 참조하십시오 "Orbited.CometTransports"

다른 전송 중 일부는 백엔드 구현에 의해 일치해야 찾습니다.