2017-09-04 2 views
1

내 코드 (모니터링 애플리케이션)에서 XMLHttpRequest 객체를 사용하여 체인 된 호출 형태로 서버를 주기적으로 호출해야합니다. 각 호출에는 정확히 15 초가 걸리고,이 기간은 서버에서 시간을 측정합니다 (HTTP 100 Continue). 현재 호출을 완료 한 직후에 현재 XMLHttpRequest 객체의 onreadystatechange 이벤트 핸들러는 다음 요청 (새 인스턴스로)을 만들어 실행해야하므로 서버와의 통신이 거의 매끄럽게 유지됩니다.XMLHttpRequest 체인 호출 리크 피하기

작동 방식에 따라 각 호출은 호출자의 객체 컨텍스트를 스택에 유지하므로 며칠 동안 열려 있어야하는 페이지이므로 스택은 가비지 수집기가 데이터를 요청할 가능성이 없어 계속 증가합니다 . 다음 스택 추적을 참조하십시오

Stack trace over a couple of minutes

나는 다음 요청을 실행하는 타이머 (setInterval을하거나)를 사용할 수 없습니다. 이전 기사의 끝 부분에서 시작해야합니다. 서버의 데이터는 가능한 한 빨리 도착해야하며, 불행히도 브라우저는 요즘 페이지에 포커스가 없을 때 타이머를 잠식합니다. 앞에서 말했듯이 이것은 사용자의 보조 모니터 (항상 초점이 맞지 않음)에서 항상 켜져 있어야하는 모니터링 응용 프로그램입니다. 또한 HTTP 시간 초과 및 15 초 시퀀스에서 벗어나는 다른 종류의 오류도 처리해야합니다. 서버에는 항상 하나의 채널 만 열려 있어야합니다.

제 질문은 XMLHttpRequest 객체를 만들 때 스택의 전체 컨텍스트를 유지하는 것을 피할 수있는 방법인지 여부입니다. DOM 객체에서 click() 메서드를 호출하더라도 스택/컨텍스트가 유지됩니다. 약속조차도 그 맥락을 지키는 것처럼 보입니다.

서버가 지원하지 않기 때문에 웹 소켓도 사용할 수 없습니다.

UPDATE : 그것은 더 복잡이야

,이 같은의 본질에 구입 :

나는 웹 노동자를 사용하여 내 문제를 해결했습니다
var xhttpObjUrl; 
var xhttpObj; 

onLoad() { 
    loadXMLDoc(pollURL + "first=1", true); 
} 

function loadXMLDoc(url, longtout) { 
    xhttpObjUrl = url; 
    xhttpObj = new XMLHttpRequest(); 
    xhttpObj.open(method, url, true); 
    xhttpObj.onprogress = progress; 
    xhttpObj.onloadend = progress; 
    xhttpObj.ontimeout = progress; 
    if (commlog) consolelog("loadXMLDoc(): url == " + dname); 
    xhttpObj.send(""); 
} 

function progress() { 
    if (!xhttpObj) return; 
    var state = xhttpObj.readyState; 
    var status; 
    var statusText; 
    if (state == 4 /* complete */ || state == 3 /* partial content */) { 
     try { 
      status = xhttpObj.status; 
      statusText = xhttpObj.statusText; 
      if (status == 200) parseServerData(); 
     } catch (err) { 
      status = 500; 
      statusText = err; 
     } 
     if (state == 4 || status != 200) { 
      /* SERVER TERMINATES THE CONNECTION AFTER 15 SECONDS */ 
      /* ERROR HANDLING REMOVED */ 
      var obj = xhttpObj; 
      xhttpObj = undefined; 
      abortRequest(obj); 
      obj = false; 
      RequestEnd(); 
     } 
    } 
} 

function RequestEnd(error) { 
    var now = (new Date).getTime(); 
    var msdiff = now - lastreqstart; 
    var code = function() { loadXMLDoc(pollURL + 'lastpoint=' + evtprev.toString() + '&lastevent=' + evtcurrent.toString()); return false; }; 
    if (msdiff < 1000) addTimedCheck(1, code); /** IGNORE THIS **/ 
    else code(); 
} 
+0

코드가 없으면 대답은 "maybe" –

+0

코드가 추가되었습니다. –

답변

0

. 작업자는 매번 XMLHttpRequest를 종료하고 페이지에 수집 된 데이터가있는 메시지를 보냅니다. 그런 다음 페이지에서 데이터 처리가 완료되면 작업자에게 새 요청을 시작하라는 메시지를 보냅니다. 따라서 내 페이지에는 요청간에 원하지 않는 지연이 발생하지 않으며 지속적으로 스택이 생성되지 않습니다. 실수로 나는 노동자를 해고하고 새로운 것을 만들 것입니다.

관련 문제