2010-01-19 2 views
5

롱 폴링 (jQuery의 ajax 기능 사용)을 사용하여 서버에서 클라이언트로 일정하거나 지속적으로 업데이트를 보내는 webapp (파이어 폭스 호환 가능)를 작성 중입니다. 하루 종일 또는 오랜 시간 동안이 작업을 종료 상태로 두는 것에 대해 우려하고 있습니다. 기본적인 코드 골격이 있습니다 :롱 폴링 Ajax 성능 개선

function processResults(xml) 
{ 
    // do stuff with the xml from the server 
} 

function fetch() 
{ 
    setTimeout(function() 
    { 
     $.ajax({ 
      type: 'GET', 
      url: 'foo/bar/baz', 
      dataType: 'xml', 
      success: function (xml) 
      { 
       processResults(xml); 
       fetch(); 
      }, 
      error: function (xhr, type, exception) 
      { 
       if (xhr.status === 0) 
       { 
       console.log('XMLHttpRequest cancelled'); 
       } 
       else 
       { 
        console.debug(xhr); 
        fetch(); 
       } 
      } 
     }); 
    }, 500); 
} 

(. 클라이언트가 업데이트를 신속하게 클라이언트로 다시 오는 경우 서버 망치하지 않도록 "절전는"0.5 초이다 - 그들은 일반적으로있는)을

밤새이 실행을 떠나고 나면 Firefox를 크롤링하는 경향이 있습니다. 나는 기본적으로 무한 재귀 함수를 작성했기 때문에 이것이 부분적으로 큰 스택 깊이로 인해 발생할 수 있다고 생각했습니다. 그러나 Firebug를 사용하여 fetch에 중단 점을 던지면이 경우가 아닌 것처럼 보입니다. Firebug가 보여 주었던 스택은 한 시간 만 지나도 4 ~ 5 프레임 정도의 깊이입니다.

내가 생각하고있는 솔루션 중 하나는 반복적 인 함수로 재귀 함수를 변경하는 것이지만 AYax 요청 사이에 지연을 삽입하는 방법을 알아낼 수는 없습니다 회전하지 않고. 나는 JS 1.7 "yield" keyword을 보았습니다.하지만 여기에 내 머리가 무엇인지 알기 위해 머리를 감쌀 수 없습니다.

매시간 한 번 주기적으로 페이지를 정기적으로 새로 고치는 것이 가장 좋은 해결책입니까? 8 시간 또는 12 시간 동안 실행 한 후에도 브라우저에 상처를주지 않는 더 나은 /보다 가벼운 긴 폴링 디자인 패턴이 있습니까? 아니면 서버의 응답 빈도를 보통 알고 있기 때문에 긴 폴링을 건너 뛰고 다른 "상수 업데이트"패턴을 사용해야합니까?

답변

2

FireBug 일 수도 있습니다. 당신은 console.logging 물건입니다. 즉, 네트워크 모니터 탭을 열어 놓은 것입니다. 이는 모든 요청이 메모리에 저장된다는 것을 의미합니다.

비활성화하면 도움이되는지 확인해보십시오.

+0

그게 나를 도와 줘 !! – JulienFr

2

메모리가 누출되는 것으로 의심됩니다 (processResults()).

오랜 폴링 웹 응용 프로그램에서 비슷한 코드를 사용하여 페이지 새로 고침없이 몇 주 동안 중단없이 실행할 수 있습니다.

스택이 깊어서는 안됩니다. fetch()이 즉시 반환되기 때문에 스택이 깊어서는 안됩니다. 무한 재귀 루프가 없습니다.

메모리 누수를 찾으려면 Firefox Leak Monitor Add-on을 사용하는 것이 좋습니다.

+0

나는 스택 깊이를 "깨뜨리는"또 다른 방법으로 생각했지만 원래 코드에서'setTimeout'과 다른 효과가있는 것을 보지 못했습니다. 가져 오기 때문에 –

+0

예, 그러나 당신의 스택() 즉시 반환, 깊은려고해서는 안된다, 그래서 성공 및 오류 기능은 꽤 빨리 스택에서 이동합니다. –

+0

당신의 기억이'processResults()'에서 유출되었다고 생각합니다. –

1

스택 깊이 4-5가 정확합니다. setTimeout$.ajax은 비동기 호출이며 즉시 반환됩니다. 콜백은 나중에 빈 호출 스택과 함께 브라우저에 의해 호출됩니다. 긴 폴링을 동기식으로 구현할 수 없으므로이 재귀 적 접근 방식을 사용해야합니다. 반복적으로 만들 방법이 없습니다.

이 속도가 느려지는 이유는 코드에 메모리 누수가있는 것 같습니다. 누출은 $.ajax (jQuery (매우)) 또는 processResults 호출에있을 수 있습니다.

1

fetch()을 메소드 자체에서 호출하는 것은 좋지 않은 생각입니다. 어떤 시점에서 메소드가 끝나고 결과가 호출자에게 보내지기를 기대할 때 재귀가 더 유용합니다.문제는 재귀 적으로 메서드를 호출 할 때 호출자 메서드를 열어두고 메모리를 사용하는 것입니다. 3-4 프레임 밖에 안되면 jQuery 나 브라우저가 어떻게 든 당신이 한 일을 "고치는"것이기 때문입니다. 기본적으로 JQuery와 지원 긴 폴링의

최근 출시. 이렇게하면 yhou가 무한 재귀 호출을 처리하기 위해 브라우저의 지능을 저하시키지 않도록 할 수 있습니다. $.ajax() 메소드를 호출하면 새 호출하기 전에 500 밀리 초의 안전한 대기와 함께 긴 설문 조사를 수행하는 아래의 코드를 사용할 수 있습니다.

function myLongPoll(){ 
    setTimeout(function(){ 
     $.ajax({ 
      type:'POST', 
      dataType: 'JSON', 
      url: 'http://my.domain.com/action', 
      data: {}, 
      cache: false, 
      success:function(data){ 

       //do something with the result 

      }, 
      complete: myLongPoll, 
      async : false, 
      timeout: 5000 
     }); 
    //Doesn't matter how long it took the ajax call, 1 milisec or 
    //5 seconds (timeout), the next call will only happen after 2 seconds 
    }, 2000); 

당신이 다음 사람이 시작되기 전에 $.ajax() 전화가 닫혀 있는지 확신 할 수 이쪽으로. 이것은 당신의 $.ajax() 호출 후 이전과 다른에서 간단한 console.log()를 추가하여 입증 할 수있다.

+0

jQuery의'complete' 콜백을 사용하는 것이 제 질문의 구현과 크게 다르지 않습니다. 이것은 Java가 아닙니다. 호출자는 XHR이나 다른 리소스를 명시 적으로 닫을 필요가 없습니다. –

관련 문제