Saya mencoba menyetel waktu tunggu pada klien HTTP yang menggunakan http.request tanpa hasil. Sejauh ini yang saya lakukan adalah:
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();
Ada petunjuk?
Jawaban:
Sekadar untuk memperjelas jawaban di atas :
Sekarang dimungkinkan untuk menggunakan
timeout
opsi dan acara permintaan yang sesuai:// set the desired timeout in options const options = { //... timeout: 3000, }; // create a request const request = http.request(options, response => { // your callback here }); // use its "timeout" event to abort the request request.on('timeout', () => { request.abort(); });
sumber
setTimeout(req.abort.bind(req), 3000);
connect
batas waktu, setelah soket dipasang, tidak akan berpengaruh. Jadi ini tidak akan membantu dengan server yang membuat soket terbuka terlalu lama (Anda masih perlu menggulirkan soket Anda sendiri dengan setTimeout).timeout : A number specifying the socket timeout in milliseconds. This will set the timeout before the socket is connected.
request.destroy
(abort
tidak digunakan lagi.) Juga, ini berbeda darisetTimeout
Pembaruan 2019
Ada berbagai cara untuk menangani ini dengan lebih elegan sekarang. Silakan lihat beberapa jawaban lain di utas ini. Teknologi bergerak cepat sehingga jawaban sering kali menjadi usang dengan cukup cepat. Jawaban saya akan tetap berfungsi tetapi ada baiknya melihat alternatif juga.
Jawaban 2012
Menggunakan kode Anda, masalahnya adalah Anda belum menunggu soket ditetapkan ke permintaan sebelum mencoba untuk mengatur barang-barang pada objek soket. Semuanya asinkron jadi:
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();
Peristiwa 'socket' dipicu ketika permintaan diberikan objek socket.
sumber
req.abort()
tampaknya tidak menjadi fungsi standar saat ini. Karenanya,socket.on
Anda mungkin ingin menyetel variabel sepertitimeout = true
dan kemudian menangani batas waktu dengan tepat di penangan responsSaat ini ada metode untuk melakukan ini secara langsung pada objek permintaan:
request.setTimeout(timeout, function() { request.abort(); });
Ini adalah metode pintasan yang mengikat acara soket dan kemudian membuat batas waktu.
Referensi: Node.js v0.8.8 Manual & Dokumentasi
sumber
Jawaban Rob Evans bekerja dengan benar untuk saya tetapi ketika saya menggunakan request.abort (), itu terjadi untuk melempar kesalahan menutup soket yang tetap tidak tertangani.
Saya harus menambahkan penangan kesalahan untuk objek permintaan:
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();
sumber
myTimeout
fungsinya? (edit: dokumen mengatakan: Sama seperti mengikat ke acara waktu tunggu nodejs.org/api/… )ECONNRESET
dapat terjadi dalam kedua kasus: klien menutup soket dan server menutup koneksi. Untuk menentukan apakah itu dilakukan oleh klien dengan meneleponabort()
adaabort
acara spceialAda metode yang lebih sederhana.
Alih-alih menggunakan setTimeout atau bekerja dengan soket secara langsung,
Kami dapat menggunakan 'batas waktu' di 'opsi' dalam penggunaan klien
Di bawah ini adalah kode server dan klien, dalam 3 bagian.
Bagian modul dan opsi:
'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 };
Bagian server:
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(); }); }
Bagian klien:
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();
Jika Anda meletakkan semua 3 bagian di atas dalam satu file, "a.js", lalu jalankan:
maka, keluarannya adalah:
startServer Server listening on http://127.0.0.1:3000 startClient timeout! 2 seconds expired got closed! got error, req.destroy() was called!
Semoga membantu.
sumber
Bagi saya - ini adalah cara yang tidak terlalu membingungkan untuk melakukan
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 ↑ }); });
sumber
Menguraikan jawaban @douwe di sini adalah tempat Anda akan memberi waktu tunggu pada permintaan http.
// TYPICAL REQUEST var req = https.get(http_options, function (res) { var data = ''; res.on('data', function (chunk) { data += chunk; }); res.on('end', function () { if (res.statusCode === 200) { /* do stuff with your data */} else { /* Do other codes */} }); }); req.on('error', function (err) { /* More serious connection problems. */ }); // TIMEOUT PART req.setTimeout(1000, function() { console.log("Server connection timeout (after 1 second)"); req.abort(); });
this.abort () juga bagus.
sumber
Anda harus meneruskan referensi ke permintaan seperti di bawah ini
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();
Peristiwa kesalahan permintaan akan dipicu
req.on("error", function(e){ console.log("Request Error : "+JSON.stringify(e)); });
sumber
Penasaran, apa yang terjadi jika Anda menggunakan straight
net.sockets
? Berikut beberapa contoh kode yang saya kumpulkan untuk tujuan pengujian: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();
sumber