traduccion socket nodejs node await node.js

node.js - socket - request npm response



NodeJS-¿Qué significa realmente "socket hang up"? (17)

Estoy construyendo un raspador web con Node y Cheerio, y para cierto sitio web recibo el siguiente error (solo ocurre en este sitio web, no en otros que trato de borrar).

Sucede en una ubicación diferente cada vez, por lo que a veces es url x que arroja el error, otras veces url x está bien y es una url diferente por completo:

Error!: Error: socket hang up using [insert random URL, it''s different every time] Error: socket hang up at createHangUpError (http.js:1445:15) at Socket.socketOnEnd [as onend] (http.js:1541:23) at Socket.g (events.js:175:14) at Socket.EventEmitter.emit (events.js:117:20) at _stream_readable.js:910:16 at process._tickCallback (node.js:415:13)

Esto es muy difícil de depurar, realmente no sé por dónde empezar. Para comenzar, ¿qué es un error de colgado de socket? ¿Es un error 404 o similar? ¿O solo significa que el servidor rechazó una conexión?

¡No puedo encontrar una explicación de esto en ningún lado!

EDITAR: Aquí hay una muestra de código que (a veces) devuelve errores:

function scrapeNexts(url, oncomplete) { request(url, function(err, resp, body) { if (err) { console.log("Uh-oh, ScrapeNexts Error!: " + err + " using " + url); errors.nexts.push(url); } $ = cheerio.load(body); // do stuff with the ''$'' cheerio content here }); }

No hay una llamada directa para cerrar la conexión, pero estoy usando Node Request que (hasta donde yo sé) usa http.get para que esto no sea necesario, http.get si estoy equivocado.

EDIT 2: Aquí hay un bit de código real en uso que está causando errores. prodURL y otras variables son en su mayoría selectores jquery que se definieron anteriormente. Esto usa la biblioteca async para Nodo.

function scrapeNexts(url, oncomplete) { request(url, function (err, resp, body) { if (err) { console.log("Uh-oh, ScrapeNexts Error!: " + err + " using " + url); errors.nexts.push(url); } async.series([ function (callback) { $ = cheerio.load(body); callback(); }, function (callback) { $(prodURL).each(function () { var theHref = $(this).attr(''href''); urls.push(baseURL + theHref); }); var next = $(next_select).first().attr(''href''); oncomplete(next); } ]); }); }


Para usuarios de módulos de request

Timeouts

Hay dos tipos principales de tiempos de espera: tiempos de espera de conexión y tiempos de espera de lectura . Se produce un tiempo de espera de conexión si se alcanza el tiempo de espera mientras el cliente intenta establecer una conexión con una máquina remota (correspondiente a la llamada de connect() en el socket). Se produce un tiempo de espera de lectura cada vez que el servidor tarda demasiado en enviar una parte de la respuesta.

Tenga en cuenta que los tiempos de espera de conexión emiten un error ETIMEDOUT , y los tiempos de espera de lectura emiten un error ECONNRESET .


Ampliando la respuesta de Blender, esto sucede en una serie de situaciones. Los más comunes con los que me encuentro son:

  1. El servidor se colgó.
  2. El servidor rechazó su conexión, muy probablemente bloqueado por User-Agent .

socketCloseListener , como se indica en la respuesta de Blender, no es el único lugar donde se crean los errores de suspensión.

Por ejemplo, encontrado here :

function socketOnEnd() { var socket = this; var req = this._httpMessage; var parser = this.parser; if (!req.res) { // If we don''t have a response then we know that the socket // ended prematurely and we need to emit an error on the request. req.emit(''error'', createHangUpError()); req._hadError = true; } if (parser) { parser.finish(); freeParser(parser, req); } socket.destroy(); }

Podría intentar curl con los encabezados y los que se envían desde Node y ver si obtiene una respuesta allí. Si no obtiene una respuesta con curl , pero obtiene una respuesta en su navegador, es muy probable que su encabezado User-Agent esté bloqueado.


Creo que vale la pena notar ...

Estaba creando pruebas para las API de Google. Estaba interceptando la solicitud con un servidor improvisado, y luego los reenvía a la API real. Intenté simplemente pasar los encabezados en la solicitud, pero algunos encabezados estaban causando un problema con Express en el otro extremo.

A saber, tuve que eliminar la connection , accept y encabezados de content-length antes de usar el módulo de solicitud para avanzar.

let headers = Object.assign({}, req.headers); delete headers[''connection''] delete headers[''accept''] delete headers[''content-length''] res.end() // We don''t need the incoming connection anymore request({ method: ''post'', body: req.body, headers: headers, json: true, url: `http://myapi/${req.url}` }, (err, _res, body)=>{ if(err) return done(err); // Test my api response here as if Google sent it. })


Eche un vistazo a la fuente :

function socketCloseListener() { var socket = this; var parser = socket.parser; var req = socket._httpMessage; debug(''HTTP socket close''); req.emit(''close''); if (req.res && req.res.readable) { // Socket closed before we emitted ''end'' below. req.res.emit(''aborted''); var res = req.res; res.on(''end'', function() { res.emit(''close''); }); res.push(null); } else if (!req.res && !req._hadError) { // This socket error fired before we started to // receive a response. The error needs to // fire on the request. req.emit(''error'', createHangUpError()); req._hadError = true; } }

El mensaje se emite cuando el servidor nunca envía una respuesta.


En caso de que esté utilizando node-http-proxy, tenga en cuenta este problema, que dará lugar a un error de socket hang-up: https://github.com/nodejitsu/node-http-proxy/issues/180 .

Para la resolución, también en este enlace, simplemente muévase declarando la ruta API (para proxying) dentro de las rutas expresas antes de express.bodyParser ().


En mi caso, fue porque una respuesta de aplicación / json estaba mal formateada (contiene un seguimiento de la pila). La respuesta nunca fue enviada al servidor. Eso fue muy complicado de depurar porque no había ningún registro. Este hilo me ayuda mucho a entender lo que sucede.


Hago desarrollo web (nodo) y Android, y abro el simulador de dispositivos Android Studio y Docker juntos, ambos usan el puerto 8601, se quejó socket hang up error de socket hang up , después de cerrar el simulador de dispositivos Android Studio y funciona bien en el nodo. No use el simulador de dispositivos Android Studio y Docker juntos.


Hay dos casos cuando se lanza el socket hang up :

Cuando eres un cliente

Cuando usted, como cliente, envía una solicitud a un servidor remoto y no recibe una respuesta oportuna. Su socket ha finalizado, lo que arroja este error. Debería detectar este error y decidir cómo manejarlo: si vuelve a intentar la solicitud, la pone en cola para más adelante, etc.

Cuando eres un servidor / proxy

Cuando usted, como servidor, quizás un servidor proxy, recibe una solicitud de un cliente, luego comienza a actuar sobre ella (o retransmite la solicitud al servidor ascendente), y antes de que haya preparado la respuesta, el cliente decide cancelar / abortar la solicitud.

Este seguimiento de pila muestra lo que sucede cuando un cliente cancela la solicitud.

Trace: { [Error: socket hang up] code: ''ECONNRESET'' } at ClientRequest.proxyError (your_server_code_error_handler.js:137:15) at ClientRequest.emit (events.js:117:20) at Socket.socketCloseListener (http.js:1526:9) at Socket.emit (events.js:95:17) at TCP.close (net.js:465:12)

Línea http.js:1526:9 puntos al mismo socketCloseListener mencionado anteriormente por @Blender, particularmente:

// This socket error fired before we started to // receive a response. The error needs to // fire on the request. req.emit(''error'', createHangUpError()); ... function createHangUpError() { var error = new Error(''socket hang up''); error.code = ''ECONNRESET''; return error; }

Este es un caso típico si el cliente es un usuario en el navegador. La solicitud para cargar algún recurso / página lleva mucho tiempo y los usuarios simplemente actualizan la página. Tal acción hace que la solicitud anterior sea abortada, lo que en su lado del servidor arroja este error.

Como este error es causado por el deseo de un cliente, no esperan recibir ningún mensaje de error. Por lo tanto, no es necesario considerar este error como crítico. Simplemente ignóralo. Esto es alentado por el hecho de que en dicho error el socket de res que su cliente escuchó es, aunque todavía puede escribirse, destruido.

console.log(res.socket.destroyed); //true

Entonces, no tiene sentido enviar algo, excepto cerrar explícitamente el objeto de respuesta:

res.end();

Sin embargo, lo que debe hacer con seguridad si es un servidor proxy que ya ha transmitido la solicitud al canal ascendente, es abortar su solicitud interna al inicio, indicando su falta de interés en la respuesta, que a su vez indicará a la parte superior servidor para, tal vez, detener una operación costosa.


Me encontré con este problema ayer al ejecutar mi aplicación web y servidor node.js a través de IntelliJ IDEA 2016.3.6. Todo lo que tuve que hacer fue borrar mis cookies y mi caché en mi navegador Chrome.


Otro caso digno de mención (para Linux y OS X) es que si utiliza una biblioteca como https para realizar las solicitudes, o si pasa https://... como una URL de la instancia servida localmente, usará el puerto 443 que es un puerto privado reservado y es posible que ECONNREFUSED en un Socket hang up o ECONNREFUSED errores ECONNREFUSED .

En su lugar, use el puerto 3000 , fe, y haga una solicitud http .


Si experimenta este error sobre una conexión https y está sucediendo al instante, podría ser un problema configurar la conexión SSL.

Para mí fue este el tema https://github.com/nodejs/node/issues/9845 pero para ti podría ser algo más. Si es un problema con el ssl, entonces debería ser capaz de reproducirlo con el paquete nodejs tls / ssl solo tratando de conectarse al dominio


También puede deberse al uso de la instancia de app de express lugar del server de const server = http.createServer(app) al crear el socket del servidor.

Incorrecto

const express = require(''express''); const http = require(''http''); const WebSocket = require(''ws''); const app = express(); app.use(function (req, res) { res.send({ msg: "hello" }); }); const wss = new WebSocket.Server({ server: app }); // will throw error while connecting from client socket app.listen(8080, function listening() { console.log(''Listening on %d'', server.address().port); });

Correcto

const express = require(''express''); const http = require(''http''); const WebSocket = require(''ws''); const app = express(); app.use(function (req, res) { res.send({ msg: "hello" }); }); const server = http.createServer(app); const wss = new WebSocket.Server({ server }); server.listen(8080, function listening() { console.log(''Listening on %d'', server.address().port); });


Tuve el mismo problema al usar la biblioteca Nano para conectarme a Couch DB . Traté de ajustar la agrupación de conexiones con el uso de la biblioteca keepaliveagent y siguió fallando con el mensaje de colgar socket .

var KeepAliveAgent = require(''agentkeepalive''); var myagent = new KeepAliveAgent({ maxSockets: 10, maxKeepAliveRequests: 0, maxKeepAliveTime: 240000 }); nano = new Nano({ url : uri, requestDefaults : { agent : myagent } });

Después de algunas dificultades pude resolver el problema, ya que salió fue un error muy, muy simple. Me estaba conectando a la base de datos a través del protocolo HTTPS, pero seguí pasando a mi objeto nano un agente keepalive creado como los ejemplos para el uso de este programa de biblioteca (se basan en algunos valores predeterminados que usan http).

Un simple cambio para usar HttpsAgent hizo el truco:

var KeepAliveAgent = require(''agentkeepalive'').HttpsAgent;


Tuve el mismo problema durante la solicitud a algún servidor. En mi caso, la configuración de cualquier valor a User-Agent en los encabezados en las opciones de solicitud me ayudó.

const httpRequestOptions = { hostname: ''site.address.com'', headers: { ''User-Agent'': ''Chrome/59.0.3071.115'' } };

No es un caso general y depende de la configuración del servidor.


Un caso que vale la pena mencionar: cuando me conecto de Node.js a Node.js usando Express, obtengo "socket colgar" si no prefijo la ruta URL solicitada con "/".


Utilicé require(''http'') para consumir el servicio https y mostró " socked hang up ".

Luego utilizo require(''https'') y funciona.


a continuación se muestra un ejemplo simple en el que recibí el mismo error cuando fallé para agregar el código comentado en el ejemplo siguiente. Descomentar el código req.end () resolverá este problema.

var fs = require("fs"); var https = require("https"); var options = { host: "en.wikipedia.org", path: "/wiki/George_Washington", port: 443, method: "GET" }; var req = https.request(options, function (res) { console.log(res.statusCode); }); // req.end();