Cet article présente principalement en détail la solution au problème de 404 longue période d'absence de réponse lorsque nodejs envoie des requêtes http
Habituellement, lorsque nous utilisons nodejs pour envoyer des requêtes http, une fois que nous rencontrons une réponse 404, Nodejs continuera à demander en interne jusqu'à ce qu'il dépasse son propre temps de réponse défini (le plus dégoûtant est que ce délai ne peut pas être modifié.) De nombreuses personnes ont rencontré des problèmes ici.
Lorsque je travaillais sur le projet de carte arcgis, le client m'a demandé d'utiliser le service de carte de base fourni par Tiantu. A cette époque, j'utilisais directement l'API Arcgis du client silverlight pour faire des requêtes http (également). une requête interne, pas une chose open source) C'est tellement frustrant), et j'ai également rencontré un problème où la barre de progression était bloquée là. Après le débogage, il a été constaté que cela était dû au délai d'attente de la demande de chargement du fond de carte. Comme nodejs, Silverlight a continué à faire des demandes jusqu'à ce que le délai de réponse qu'il s'était fixé soit dépassé.
Donc, j'avais une certaine exposition amateur à nodejs à cette époque, et je pensais que les performances de cette chose devraient être bonnes, au moins meilleures que tomcat+java et autres. J'ai donc commencé à écrire un service proxy nodejs pour demander la carte de base de la carte du ciel. À cette époque, je pensais que nodejs pouvait directement mettre fin à la requête en rencontrant 404. Cependant, ce problème semble être un standard de l'industrie. Il continue également à faire des requêtes comme Silverlight... J'ai simplement vérifié les informations en ligne et j'ai trouvé ce qui suit. deux paragraphes. Le code résout le problème de toujours demander 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; }
Le principe est d'utiliser plusieurs événements et timers demandés par nodejs. Une fois le temps de réponse défini dépassé, la requête sera immédiatement terminée. De cette façon, le problème du blocage de la barre de progression est résolu.
Les lecteurs attentifs ont peut-être vu le code
path.exists(filename, function(exists) { if (exists) { readFileEntry(filename,that.res); }else{...});
. En fait, la mise en cache des images côté serveur est effectuée ici. Une fois l'image de fond de carte chargée, elle est lue directement depuis la zone locale, ce qui est grandement utile. accélère le processus. Vitesse d’accès à la carte améliorée (cela améliore l’efficacité d’au moins 10 fois).
Quant à la façon dont l'API Arcgis pour Silverlight implémente le chargement des fonds de carte du ciel et d'autres services de fond de carte (tels que les services de fond de carte du système de coordonnées locales Mercator non standard) ? S'il vous plaît, écoutez mon explication la prochaine fois.
J'ai compilé ce qui précède pour vous, j'espère que cela vous sera utile à l'avenir.
Articles connexes :
Comment implémenter le chargement paresseux des routes dans vue-router
Comment implémenter le débogage des points d'arrêt des fichiers ts dans Angular2
Comment faire défiler la page Web vers le haut
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!