nodejs - require('' http '') node js
¿Cómo establecer un tiempo de espera en http.request() en Node? (8)
Curioso, ¿qué pasa si usas net.sockets
en net.sockets
lugar? Aquí hay un código de muestra que reuní para fines de prueba:
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();
Estoy intentando establecer un tiempo de espera en un cliente HTTP que utiliza http.request sin suerte. Hasta ahora lo que hice fue esto:
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();
¿Algún consejo?
Debe pasar la referencia para solicitarla como a continuación
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();
El evento de error de solicitud se activará
req.on("error", function(e){
console.log("Request Error : "+JSON.stringify(e));
});
El guante de Rob Evans funciona correctamente para mí, pero cuando uso request.abort (), se produce un error de suspensión del socket que no se controla.
Tuve que agregar un controlador de errores para el objeto de solicitud:
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();
En este momento hay un método para hacer esto directamente en el objeto de solicitud:
request.setTimeout(timeout, function() {
request.abort();
});
Este es un método abreviado que se une al evento socket y luego crea el tiempo de espera.
Referencia: Node.js v0.8.8 Manual y documentación
En la respuesta @douwe aquí es donde pondría un tiempo de espera en una solicitud 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 () también está bien.
Hay un método más simple.
En lugar de usar setTimeout o trabajar con socket directamente,
Podemos usar ''timeout'' en las ''opciones'' en los usos del cliente
A continuación se muestra el código de servidor y cliente, en 3 partes.
Parte del módulo y opciones:
''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
};
Parte del servidor:
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();
});
}
Parte del cliente:
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();
Si coloca todas las 3 partes anteriores en un archivo, "a.js", y luego ejecuta:
node a.js
entonces, la salida será:
startServer
Server listening on http://127.0.0.1:3000
startClient
timeout! 2 seconds expired
got closed!
got error, req.destroy() was called!
Espero que ayude.
Para mí, aquí hay una forma menos confusa de hacer el 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 ↑
});
});
Usando su código, el problema es que no ha esperado a que se le asigne un socket a la solicitud antes de intentar establecer cosas en el objeto socket. Todo es asínc entonces:
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();
El evento ''socket'' se dispara cuando a la solicitud se le asigna un objeto socket.