视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
在nodejs中遇到404长时间未响应
2020-11-27 19:35:59 责编:小OO
文档

这篇文章主要为大家详细介绍了nodejs发送http请求时遇到404长时间未响应的解决方法

通常,我们在使用nodejs发送http请求时,一旦遇到404响应,nodejs内部会一直请求下去,直到超出它自己设定的响应时长(最让人恶心的地方就是这个时长还是没法修改的。)很多人在这里碰到了麻烦。

我是在做arcgis地图项目的时候,客户提出需要使用天地图提供的底图服务,当时我直接使用silverlight客户端的Arcgis API进行http请求(同样是内部请求,不开源的东西就是这么让人郁闷),同样碰到了一个进度条一直卡在那的问题。经过调试发现,是由于底图加载请求超时的缘故,和nodejs一样,silverlight一直在进行请求直到超出它自己设定的响应时限。

于是,我当时正好有业余接触nodejs,觉得这个东西性能应该是不错的,至少比tomcat+java之流要好一些。于是,我着手写了一个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 是如何实现天地图底图以及其它底图服务(比如非标准墨卡托的地方坐标系底图服务)加载的呢?请听我下回分解。

上面是我整理给大家的,希望今后会对大家有帮助。

相关文章:

在vue-router中如何实现路由懒加载

在Angular2中如何实现断点调试ts文件

如何实现网页快报向上滚动

下载本文
显示全文
专题