如何在Node上的http.request()设置超时?

我试图设置一个HTTP客户端使用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(); 

任何提示?

使用你的代码,问题是在尝试设置套接字对象的东西之前,你还没有等待一个套接字被分配给请求。 这都是asynchronous的:

 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(); }); 

这是绑定到套接字事件,然后创build超时的快捷方法。

参考: Node.js v0.8.8手册和文档

Rob Evans anwser对我来说工作正常,但是当我使用request.abort()时,它会抛出一个socket挂起错误,并保持未处理状态。

我不得不为请求对象添加一个error handling程序:

 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(); 

你应该通过参考请求如下

 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(); 

对我来说 – 这是一个不太令人困惑的做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 ↑ }); }); 

好奇,如果你使用直接的net.sockets ,会发生什么? 下面是我为了testing目的而放置的一些示例代码:

 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();