我試圖在超時或錯誤時自動重試HTTP請求。
目前我的代碼看起來是這樣的:Nodejs http在超時或錯誤時重試
var req = http.get(url, doStuff)
.on('error', retry)
.setTimeout(10000, retry);
然而,單個請求有時可以同時觸發「上的錯誤」和「超時」事件。什麼是更好的實施重試的方式?
我試圖在超時或錯誤時自動重試HTTP請求。
目前我的代碼看起來是這樣的:Nodejs http在超時或錯誤時重試
var req = http.get(url, doStuff)
.on('error', retry)
.setTimeout(10000, retry);
然而,單個請求有時可以同時觸發「上的錯誤」和「超時」事件。什麼是更好的實施重試的方式?
你可以嘗試這樣的事:
function doRequest(url, callback) {
var timer,
req,
sawResponse = false;
req = http.get(url, callback)
.on('error', function(err) {
clearTimeout(timer);
req.abort();
// prevent multiple execution of `callback` if error after
// response
if (!sawResponse)
doRequest(url, callback);
}).on('socket', function(sock) {
timer = setTimeout(function() {
req.abort();
doRequest(url, callback);
}, 10000);
}).once('response', function(res) {
sawResponse = true;
clearTimeout(timer);
});
}
UPDATE:在節點的最近/現代版本,您現在可以指定一個timeout
選項(以毫秒計),其設置套接字超時(前插座已連接)。例如:
http.get({
host: 'example.org',
path: '/foo',
timeout: 5000
}, (res) => {
// ...
});
這是我工作的代碼。關鍵是在超時後銷燬套接字以及檢查響應是否完成。
function httpGet(url, callback) {
var retry = function(e) {
console.log("Got error: " + e.message);
httpGet(url, callback); //retry
}
var req = http.get(url, function(res) {
var body = new Buffer(0);
res.on('data', function (chunk) {
body = Buffer.concat([body, chunk]);
});
res.on('end', function() {
if(this.complete) callback(body);
else retry({message: "Incomplete response"});
});
}).on('error', retry)
.setTimeout(20000, function(thing){
this.socket.destroy();
});
}
我在找同樣的東西,發現有趣的模塊requestretry,非常適合這樣的要求。
下面是用法:
var request = require('requestretry')
request({
url: myURL,
json: true,
maxAttempts: 5, // (default) try 5 times
retryDelay: 5000, // (default) wait for 5s before trying again
retrySrategy: request.RetryStrategies.HTTPOrNetworkError // (default) retry on 5xx or network errors
}, function(err, response, body){
// this callback will only be called when the request succeeded or after maxAttempts or on error
if (response) {
console.log('The number of request attempts: ' + response.attempts);
}
})
爲什麼這個downvoted,我不知道? – Holf 2016-12-16 13:57:23
@Holf不知道,我只是回答,因爲我認爲這個模塊是針對問題提到的問題的完美解決方案。我使用了模塊,它工作得很好。 – Gagan 2016-12-21 09:14:26
是的,我也發現它是完美的解決方案。 – Holf 2016-12-21 10:03:04