如何在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();