This article mainly introduces in detail the solution to 404 long-term unresponsiveness when nodejs sends http requests.
Usually, when we use nodejs to send http requests, once we encounter a 404 response, Nodejs will keep requesting internally until it exceeds its own set response time (the most disgusting part is that this time period cannot be modified.) Many people have encountered trouble here.
When I was working on the arcgis map project, the customer asked me to use the base map service provided by Tiantu. At that time, I directly used the Arcgis API of the silverlight client to make http requests (also internal requests, not open source) It’s so frustrating), and I also encountered a problem where the progress bar was always stuck there. After debugging, it was found that it was due to the basemap loading request timeout. Like nodejs, silverlight kept making requests until the response time limit it set itself was exceeded.
So, I happened to have amateur contact with nodejs at that time, and I felt that the performance of this thing should be good, at least better than tomcat java and the like. So, I started writing a nodejs proxy service to request the base map of the sky map. At that time, I thought that nodejs could directly end the request when encountering 404. However, this problem seems to be an industry standard. It also keeps making requests like silverlight... I simply checked the information online and came up with the following two paragraphs. The code solves the problem of always requesting 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; }
The principle is to use several events and timers requested by nodejs. Once the set response time is exceeded, the request will be terminated immediately. In this way, the problem of the progress bar being stuck is solved.
Careful readers may have seen this code
path.exists(filename, function(exists) { if (exists) { readFileEntry(filename,that.res); }else{...});
. In fact, server-side image caching is done here. Once the basemap image is loaded, it is read directly from the local area, which greatly speeds up the map. Access speed (this improves efficiency by at least 10 times).
As for how Arcgis API for Silverlight implements the loading of sky map basemaps and other basemap services (such as non-standard Mercator local coordinate system basemap services)? Please listen to my explanation next time.
The above is what I compiled for everyone. I hope it will be helpful to everyone in the future.
Related articles:
How to implement lazy loading of routes in vue-router
How to implement breakpoint debugging of ts files in Angular2
How to scroll up the webpage express
The above is the detailed content of Encountered 404 long time unresponsive in nodejs. For more information, please follow other related articles on the PHP Chinese website!