nodejs 가 http 요청 을 보 낼 때 404 오랫동안 응답 하지 않 은 해결 방법 을 만 났 습 니 다.

5305 단어 nodejshttp404
보통 nodejs 를 사용 하여 http 요청 을 보 낼 때 404 응답 을 받 으 면 nodejs 내부 에서 자신 이 설정 한 응답 시간 을 초과 할 때 까지 계속 요청 합 니 다.(가장 징 그 러 운 곳 은 이 시간 입 니 다.수정 할 수 없습니다.)많은 사람들 이 이곳 에서 문 제 를 만 났 다.
저 는 arcgis 지도 프로젝트 를 할 때 고객 이 천 지도 로 제공 하 는 밑그림 서 비 스 를 사용 해 야 한다 고 제 안 했 습 니 다.그 당시 에 저 는 silverlight 클 라 이언 트 의 Arcgis API 를 직접 사용 하여 http 요청 을 했 습 니 다.디 버 깅 을 통 해 알 수 있 듯 이 밑그림 로 딩 요청 시간 이 초과 되 었 기 때문에 nodejs 와 마찬가지 로 silverlight 는 자신 이 설정 한 응답 시간 을 초과 할 때 까지 계속 요청 하고 있 습 니 다.
그래서 저 는 여가 시간 에 nodejs 를 접 했 습 니 다.이 물건 의 성능 이 좋 을 것 이 라 고 생각 했 습 니 다.적어도 tomcat+자바 류 보다 좋 았 습 니 다.그래서 나 는 하늘 지도 에 대한 밑그림 을 요청 하기 위해 nodejs 의 대리 서 비 스 를 손 으로 썼 다.나 는 당시 에 nodejs 가 404 에 부 딪 혔 을 때 직접 요청 을 끝 낼 수 있 을 것 이 라 고 생각 했다.그러나 이 문 제 는 마치 업계 규범 인 것 처럼 silverlight 와 같은 끊 임 없 는 요청 이 었 다.아예 인터넷 에서 회의 자 료 를 찾 아 다음 과 같은 두 개의 코드 를 얻어 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 는 어떻게 천 지도 밑그림 과 다른 밑그림 서비스(예 를 들 어 표준 머 카 토 가 아 닌 지방 좌표계 밑그림 서비스)를 불 러 옵 니까?다음 회의 설명 을 들 어 주세요.
이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.

좋은 웹페이지 즐겨찾기