2011-06-02 26 views
67

मैं एक HTTP क्लाइंट पर टाइमआउट सेट करने का प्रयास कर रहा हूं जो कि किसी भी भाग्य के साथ http.request का उपयोग करता है। अब तक मैंने यह किया है:नोड में http.request() पर टाइमआउट कैसे सेट करें?

var options = { ... } 
var req = http.request(options, function(res) { 
    // Usual stuff: on(data), on(end), chunks, etc... 
} 

/* This does not work TOO MUCH... sometimes the socket is not ready (undefined) expecially on rapid sequences of requests */ 
req.socket.setTimeout(myTimeout); 
req.socket.on('timeout', function() { 
    req.abort(); 
}); 

req.write('something'); 
req.end(); 

कोई संकेत?

+1

यह उत्तर मिला (यह भी काम करता है) लेकिन मुझे आश्चर्य है कि http.request() http://stackoverflow.com/questions/6129240/how-to-set-timeout-for-http-createclient के लिए कुछ अलग है या नहीं -in-node-js – Claudio

उत्तर

0

उत्सुक, यदि आप सीधे net.sockets का उपयोग करते हैं तो क्या होता है? यहाँ मैं परीक्षण प्रयोजनों के लिए एक साथ रखा कुछ नमूना कोड:

var net = require('net'); 

function HttpRequest(host, port, path, method) { 
    return { 
    headers: [], 
    port: 80, 
    path: "/", 
    method: "GET", 
    socket: null, 
    _setDefaultHeaders: function() { 

     this.headers.push(this.method + " " + this.path + " HTTP/1.1"); 
     this.headers.push("Host: " + this.host); 
    }, 
    SetHeaders: function(headers) { 
     for (var i = 0; i < headers.length; i++) { 
     this.headers.push(headers[i]); 
     } 
    }, 
    WriteHeaders: function() { 
     if(this.socket) { 
     this.socket.write(this.headers.join("\r\n")); 
     this.socket.write("\r\n\r\n"); // to signal headers are complete 
     } 
    }, 
    MakeRequest: function(data) { 
     if(data) { 
     this.socket.write(data); 
     } 

     this.socket.end(); 
    }, 
    SetupRequest: function() { 
     this.host = host; 

     if(path) { 
     this.path = path; 
     } 
     if(port) { 
     this.port = port; 
     } 
     if(method) { 
     this.method = method; 
     } 

     this._setDefaultHeaders(); 

     this.socket = net.createConnection(this.port, this.host); 
    } 
    } 
}; 

var request = HttpRequest("www.somesite.com"); 
request.SetupRequest(); 

request.socket.setTimeout(30000, function(){ 
    console.error("Connection timed out."); 
}); 

request.socket.on("data", function(data) { 
    console.log(data.toString('utf8')); 
}); 

request.WriteHeaders(); 
request.MakeRequest(); 
+0

यदि मैं सॉकेट टाइमआउट का उपयोग करता हूं, और मैं दो अनुरोधों को एक के बाद जारी करता हूं (पहले खत्म होने की प्रतीक्षा किए बिना), दूसरे अनुरोध में सॉकेट अपरिभाषित है (कम से कम इस समय मैं टाइमआउट सेट करने का प्रयास करता हूं) .. शायद सॉकेट पर कुछ ("तैयार") होना चाहिए ... मुझे नहीं पता। – Claudio

+0

@ क्लाउडियो क्या आप एकाधिक कोड दिखाने के लिए अपना कोड अपडेट कर सकते हैं? –

+1

बेशक ... यह थोड़ा लंबा है और यदि मैंने कोई समस्या नहीं है तो मैंने paste2.org का उपयोग किया: http://paste2.org/p/1448487 – Claudio

79

अपने कोड का उपयोग करना, मुद्दा यह है कि आप के लिए एक सॉकेट सॉकेट वस्तु पर सामान सेट करने के लिए प्रयास करने से पहले अनुरोध करने के लिए आवंटित करने के लिए इंतजार कर रहे थे नहीं किया है। यह सब इतना async है: जब अनुरोध सॉकेट वस्तु असाइन किया गया है

var options = { ... } 
var req = http.request(options, function(res) { 
    // Usual stuff: on(data), on(end), chunks, etc... 
}); 

req.on('socket', function (socket) { 
    socket.setTimeout(myTimeout); 
    socket.on('timeout', function() { 
     req.abort(); 
    }); 
}); 

req.on('error', function(err) { 
    if (err.code === "ECONNRESET") { 
     console.log("Timeout occurs"); 
     //specific error treatment 
    } 
    //other error treatment 
}); 

req.write('something'); 
req.end(); 

'सॉकेट' घटना निकाल दिया जाता है।

request.setTimeout(timeout, function() { 
    request.abort(); 
}); 

यह एक शॉर्टकट विधि सॉकेट घटना को बांधता है और उसके बाद का समय समाप्त बनाता है:

+0

यह वास्तव में, कुल समझ में आता है। समस्या यह है कि अब मैं इस विशेष मुद्दे का परीक्षण नहीं कर सकता (समय बीतता है ...)। तो मैं अभी जवाब के लिए केवल जवाब दे सकता हूं :) धन्यवाद। – Claudio

+0

कोई चिंता नहीं। ध्यान रखें कि यह केवल नोड के नवीनतम संस्करण पर काम करता है जहां तक ​​मुझे पता है। मैंने पिछले संस्करण (5.0.3-प्री) पर परीक्षण किया था, मुझे लगता है और यह सॉकेट घटना को नहीं चला था। –

+1

इसे संभालने का दूसरा तरीका एक बोग-मानक सेटटाइमआउट कॉल का उपयोग करना है। आपको setTimeout आईडी को इसके साथ रखने की आवश्यकता होगी: var id = setTimeout (...); ताकि यदि आप किसी डेटा को प्राप्त करते हैं तो आप इसे रद्द कर सकते हैं। एक अच्छा तरीका यह अनुरोध ऑब्जेक्ट में स्वयं को स्टोर करना है, फिर स्पष्ट करें कि अगर आपको कुछ डेटा मिलता है तो उसे हटा दें। –

28

इस समय वहाँ अनुरोध वस्तु पर सीधे यह करने के लिए एक विधि है।

संदर्भ: Node.js v0.8.8 Manual & Documentation

+3

request.setTimeout में उचित समय-समय पर सॉफ़्टवेयर को सॉकेट पर निष्क्रियता के टाइमआउट मिलीसेकंड के बाद सॉकेट सेट करते हैं। " मुझे लगता है कि यह सवाल गतिविधि के बावजूद अनुरोध को समाप्त करने के बारे में है। – ostergaard

+0

कृपया ध्यान दें कि, नीचे दिए गए उत्तरों में जैसा कि सीधे शामिल सॉकेट का उपयोग करता है, req.abort() एक त्रुटि घटना का कारण बनता है, जिसे ('त्रुटि') आदि द्वारा नियंत्रित किया जाना चाहिए। – KLoozen

+4

request.setTimeout नहीं होगा अनुरोध को निरस्त करें, हमें टाइमआउट कॉलबैक में मैन्युअल रूप से निरस्त करने की आवश्यकता है। – Udhaya

17

रोब इवांस anwser मेरे लिए ठीक से काम करता है, लेकिन जब मैं request.abort() का उपयोग, यह फेंकने के लिए एक सॉकेट त्रुटि जो बिना क्रिया रहता लटका होता है।

var options = { ... } 
var req = http.request(options, function(res) { 
    // Usual stuff: on(data), on(end), chunks, etc... 
} 

req.on('socket', function (socket) { 
    socket.setTimeout(myTimeout); 
    socket.on('timeout', function() { 
     req.abort(); 
    }); 
} 

req.on('error', function(err) { 
    if (err.code === "ECONNRESET") { 
     console.log("Timeout occurs"); 
     //specific error treatment 
    } 
    //other error treatment 
}); 

req.write('something'); 
req.end(); 
+1

'myTimeout' फ़ंक्शन कहां है? (संपादित करें: दस्तावेज़ कहते हैं: टाइमआउट ईवेंट के लिए बाध्यकारी के समान ही https://nodejs.org/api/http.html#http_request_settimeout_timeout_callback) –

+0

ध्यान दें कि 'ECONNRESET' दोनों मामलों में हो सकता है: क्लाइंट सॉकेट बंद करता है और सर्वर कनेक्शन बंद कर देता है। यह निर्धारित करने के लिए कि क्या यह 'abort()' कॉल करके क्लाइंट द्वारा किया गया था, वहां spceial 'abort' ईवेंट है – Derp

2

आप की तरह नीचे

var options = { ... } 
 
var req = http.request(options, function(res) { 
 
    // Usual stuff: on(data), on(end), chunks, etc... 
 
}); 
 

 
req.setTimeout(60000, function(){ 
 
    this.abort(); 
 
}.bind(req); 
 
req.write('something'); 
 
req.end();

अनुरोध त्रुटि घटना मिलेगा अनुरोध करने के लिए संदर्भ से पारित करना चाहिए:

मैं अनुरोध वस्तु के लिए एक त्रुटि हैंडलर जोड़ने के लिए किया था ट्रिगर

req.on("error", function(e){ 
 
     console.log("Request Error : "+JSON.stringify(e)); 
 
    });

2

मुझे के लिए - यहाँ socket.setTimeout

var request=require('https').get(
    url 
    ,function(response){ 
     var r=''; 
     response.on('data',function(chunk){ 
      r+=chunk; 
      }); 
     response.on('end',function(){ 
      console.dir(r);   //end up here if everything is good! 
      }); 
     }).on('error',function(e){ 
      console.dir(e.message); //end up here if the result returns an error 
      }); 
request.on('error',function(e){ 
    console.dir(e);     //end up here if a timeout 
    }); 
request.on('socket',function(socket){ 
    socket.setTimeout(1000,function(){ 
     request.abort();    //causes error event ↑ 
     }); 
    }); 
1

कर रहे सरल तरीका है की एक कम भ्रामक तरीका है।

इसके बजाय setTimeout का उपयोग कर या सीधे सॉकेट साथ काम करने का

,
हम ग्राहक में 'विकल्प' में 'टाइमआउट' का उपयोग कर सकते का उपयोग करता

नीचे 3 भागों में, दोनों सर्वर और ग्राहक के कोड है।

मॉड्यूल और विकल्प हिस्सा:

'use strict'; 

// Source: https://github.com/nodejs/node/blob/master/test/parallel/test-http-client-timeout-option.js 

const assert = require('assert'); 
const http = require('http'); 

const options = { 
    host: '127.0.0.1', // server uses this 
    port: 3000, // server uses this 

    method: 'GET', // client uses this 
    path: '/', // client uses this 
    timeout: 2000 // client uses this, timesout in 2 seconds if server does not respond in time 
}; 

सर्वर हिस्सा:

function startServer() { 
    console.log('startServer'); 

    const server = http.createServer(); 
    server 
      .listen(options.port, options.host, function() { 
       console.log('Server listening on http://' + options.host + ':' + options.port); 
       console.log(''); 

       // server is listening now 
       // so, let's start the client 

       startClient(); 
      }); 
} 

ग्राहक हिस्सा:

function startClient() { 
    console.log('startClient'); 

    const req = http.request(options); 

    req.on('close', function() { 
     console.log("got closed!"); 
    }); 

    req.on('timeout', function() { 
     console.log("timeout! " + (options.timeout/1000) + " seconds expired"); 

     // Source: https://github.com/nodejs/node/blob/master/test/parallel/test-http-client-timeout-option.js#L27 
     req.destroy(); 
    }); 

    req.on('error', function (e) { 
     // Source: https://github.com/nodejs/node/blob/master/lib/_http_outgoing.js#L248 
     if (req.connection.destroyed) { 
      console.log("got error, req.destroy() was called!"); 
      return; 
     } 

     console.log("got error! ", e); 
    }); 

    // Finish sending the request 
    req.end(); 
} 


startServer(); 

आप एक फ़ाइल में सब से ऊपर 3 भागों रखते हैं, "एक .js ", और उसके बाद चलाएँ:

node a.js 

तो, उत्पादन होगा:

startServer 
Server listening on http://127.0.0.1:3000 

startClient 
timeout! 2 seconds expired 
got closed! 
got error, req.destroy() was called! 

आशा है कि मदद करता है।

संबंधित मुद्दे