>  기사  >  웹 프론트엔드  >  nodejs에서 오랫동안 응답하지 않는 404가 발생했습니다.

nodejs에서 오랫동안 응답하지 않는 404가 발생했습니다.

亚连
亚连원래의
2018-06-21 17:08:321328검색

이 글에서는 nodejs가 http 요청을 보낼 때 404 오랜 시간 응답이 없는 문제에 대한 해결 방법을 주로 자세히 소개합니다.

보통 nodejs를 사용하여 http 요청을 보낼 때 404 응답이 발생하면 nodejs는 내부적으로 계속 요청합니다. , 자체 설정된 응답 시간을 초과할 때까지(가장 역겨운 부분은 이 기간을 수정할 수 없다는 것입니다.) 많은 사람들이 여기서 문제를 겪었습니다.

arcgis 지도 프로젝트를 진행하던 중, 고객께서 Tiantu에서 제공하는 기본 지도 서비스를 이용해달라고 요청하셨습니다. 당시 저는 Silverlight 클라이언트의 Arcgis API를 직접 사용하여 http 요청을 했습니다(이 역시 내부 서비스였습니다. 오픈 소스가 아닌 것들이 너무 혼란스럽습니다.) 진행률 표시줄이 계속 멈추는 문제도 발생했습니다. 디버깅 후, nodejs와 마찬가지로 Silverlight도 자체적으로 설정한 응답 시간 제한을 초과할 때까지 계속 요청을 했기 때문에 발생한 것으로 확인되었습니다.

그래서 저는 그 당시 우연히 nodejs에 대한 아마추어 노출을 겪었고, 이 제품의 성능은 적어도 tomcat+java 등과 같은 것보다 좋아야 한다고 느꼈습니다. 그래서 저는 하늘 지도의 기본 지도를 요청하기 위해 nodejs 프록시 서비스를 작성하기 시작했습니다. 당시에는 nodejs가 404를 만나면 바로 요청을 종료할 수 있을 거라 생각했는데, 이 문제는 업계 표준인 것 같습니다. 역시 실버라이트 같은 요청을 계속 하는군요... 간단하게 온라인에서 정보를 확인해보니 다음과 같은 내용이 나왔습니다. 이 코드는 항상 404를 요청하는 문제를 해결합니다.

function proxyTDTMapData(img,level,row,col){ 
  var that = this,request = null,param = img.replace('_w',''); 
  var filename = tdtimgDir+'/'+img+'_'+level+'_'+row+'_'+col+'.png'; 
  path.exists(filename, function(exists) { 
    if (exists) { 
      readFileEntry(filename,that.res); 
    }else{ 
      var url = "http://t0.tianditu.com/"+img+"/wmts?service=wmts&request=GetTile&version=1.0.0&LAYER=" + param + "&tileMatrixSet=w&TileRow=" + row + "&TileCol=" + col + "&TileMatrix=" + level + "&style=default&format=tiles"; 
       
      httpGetWithTimeoutSupport(url,4000,function(response){ 
        //console.log("have a response!"); 
        if(200 == response.statusCode){ 
          var size = 0; 
          var chunks = []; 
          response.on('data', function(chunk){ 
            size += chunk.length; 
            chunks.push(chunk); 
          }); 
          response.on('end', function(){ 
            var data = Buffer.concat(chunks, size); 
            that.res.writeHead(200, { 
              'Content-Type' : 'image/png', 
              'Content-Length' : data.length, 
              'Accept-Ranges' : 'bytes', 
              'Server' : 'Microsoft-IIS/7.5', 
              'X-Powered-By' : 'ASP.NET' 
            }); 
            that.res.write(data, "binary"); 
            that.res.end(); 
            fs.writeFile(tdtimgDir+'/'+img+'_'+level+'_'+row+'_'+col+'.png', data); 
           }); 
        }else{ 
          readFileEntry(mapDir+"/null.png",that.res); 
        } 
      }).on("error",function(){ 
        readFileEntry(mapDir+"/null.png",that.res); 
      }); 
    } 
  }); 
   
   
 }
function httpGetWithTimeoutSupport(options, timeout, callback) { 
  var timeoutEvent; 
 
  var req = http.get(options, function(res) { 
    res.on("end", function() { 
      clearTimeout(timeoutEvent); 
      // console.log("end"); 
    }) 
    res.on("close", function(e) { 
      clearTimeout(timeoutEvent); 
      // console.log("close"); 
    }) 
 
    res.on("abort", function() { 
      // console.log("abort"); 
    }); 
 
    res.on("error",function(){ 
      try{ 
        res.destory(); 
        clearTimeout(timeoutEvent); 
        //console.log("res error catch"); 
      }catch(e){ 
       
      } 
    }); 
    callback(res); 
  }); 
 
  req.on("timeout", function() { 
    //console.log("request emit timeout received"); 
    try{ 
      if (req.res) { 
        req.res.emit("abort"); 
      } 
      clearTimeout(timeoutEvent); 
      req.abort(); 
    }catch(e){ 
      //console.log("req timeout failed!"); 
    } 
  }); 
  req.on("error",function(){ 
    try{ 
      //console.log("req error catch"); 
    }catch(e){ 
     
    } 
  }); 
  timeoutEvent = setTimeout(function() { 
    try{ 
      req.emit("timeout"); 
    }catch(e){ 
      //console.log("timeout failed!"); 
    } 
  }, timeout); 
 
  return req; 
}

nodejs에서 요청한 여러 이벤트와 타이머를 사용하는 것이 원칙입니다. 설정된 응답 시간을 초과하면 요청이 즉시 종료됩니다. 이렇게 하면 진행률 표시줄이 멈추는 문제가 해결됩니다.
주의 깊은 독자라면

path.exists(filename, function(exists) { 
    if (exists) { 
      readFileEntry(filename,that.res); 
    }else{...});

이 코드를 본 적이 있을 것입니다. 실제로 서버측 이미지 캐싱은 여기서 이루어집니다. 베이스맵 이미지가 로드되면 로컬 영역에서 직접 읽어들여 지도 액세스 속도가 크게 향상됩니다. 효율성이 최소 10배 이상 향상됩니다.
Arcgis API for Silverlight가 하늘 지도 베이스맵 및 기타 베이스맵 서비스(예: 비표준 Mercator 로컬 좌표계 베이스맵 서비스) 로드를 구현하는 방법은 무엇입니까? 다음에는 제 설명을 들어주세요.

위 내용은 제가 여러분을 위해 정리한 내용입니다. 앞으로 도움이 되길 바랍니다.

관련 기사:

vue-router에서 경로 지연 로드를 구현하는 방법

Angular2에서 ts 파일의 중단점 디버깅을 구현하는 방법

웹 페이지 위로 스크롤을 구현하는 방법

위 내용은 nodejs에서 오랫동안 응답하지 않는 404가 발생했습니다.의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.