Estoy construyendo un raspador web con Node y Cheerio, y para un determinado sitio web obtengo el siguiente error (solo ocurre en este sitio web, no en otros que intento raspar).
Ocurre en una ubicación diferente cada vez, por lo que a veces es url x
el error, otras veces url x
está bien y es una URL completamente diferente:
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 colgar el 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 lo Node Request
que (por lo que puedo decir) usa, http.get
así que esto no es obligatorio, ¡corríjame si me equivoco!
EDITAR 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 async
biblioteca para Node.
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);
}
]);
});
}
end
evento de conexión dentro del período de tiempo de espera. Si recibe la solicitud de cheerio a través dehttp.request
(nohttp.get
). Debe llamarrequest.end()
para terminar de enviar la solicitud.request
servicio de nodo , no unahttp.request
solicitud específica (¡creo que soy muy nuevo en el nodo!). Este es el siguiente: github.com/mikeal/request Parece que finaliza la solicitud automáticamente, ¿no? EDITAR: Según los documentos,http method, defaults to GET
ese no es el problema.cheerio.load
es asíncrono. Por lo tanto, puede que no termine antes de comenzar a hacer cosas con $.hang up
significa terminar una conversación electrónica cortando la conexión ; se originó al colgar el teléfono antiguo.Respuestas:
Hay dos casos cuando
socket hang up
se lanza:Cuando eres cliente
Cuando usted, como cliente, envía una solicitud a un servidor remoto y no recibe una respuesta oportuna. Su zócalo está terminado, lo que arroja este error. Debe detectar este error y decidir cómo manejarlo: si volver a intentar la solicitud, ponerla en cola para más adelante, etc.
Cuando eres un servidor / proxy
Cuando usted, como servidor, tal vez 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 / cancelar la solicitud.
Este seguimiento de la pila muestra lo que sucede cuando un cliente cancela la solicitud.
La línea
http.js:1526:9
apunta a lo mismosocketCloseListener
mencionado anteriormente por @Blender, particularmente:Este es un caso típico si el cliente es un usuario en el navegador. La solicitud de cargar algún recurso / página lleva mucho tiempo, y los usuarios simplemente actualizan la página. Dicha acción hace que la solicitud anterior se anule, lo que en el lado del servidor arroja este error.
Dado que 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 se ve alentado por el hecho de que, en tal error, el
res
socket que escuchó su cliente es, aunque aún se puede escribir, destruido.Entonces, no tiene sentido enviar nada, excepto cerrar explícitamente el objeto de respuesta:
Sin embargo, lo que debe hacer con certeza si es un servidor proxy que ya ha transmitido la solicitud a la cadena ascendente, es cancelar su solicitud interna a la cadena ascendente, lo que indica su falta de interés en la respuesta, que a su vez informará a la cadena ascendente servidor para, quizás, detener una operación costosa.
fuente
setTimeout()
. vea esta pregunta: stackoverflow.com/questions/6214902/…res.send
, graciaskeep-alive
. Y en caso de que su cliente lo espere, obtendrá el error. Se ve a lo largo de las siguientes líneas .Echa un vistazo a la fuente :
El mensaje se emite cuando el servidor nunca envía una respuesta.
fuente
Un caso que vale la pena mencionar: cuando me conecto desde Node.js a Node.js usando Express, obtengo un "bloqueo del socket" si no prefijo la ruta URL solicitada con "/".
fuente
Solía
require('http')
consumir el servicio https y mostraba "socket hang up
".Luego cambié
require('http')
a en surequire('https')
lugar, y está funcionando.fuente
A continuación se muestra un ejemplo simple donde obtuve el mismo error cuando no pude agregar el código comentado en el ejemplo a continuación. Descomentar el código
req.end()
resolverá este problema.fuente
Ampliando la respuesta de Blender, esto sucede en una serie de situaciones. Los más comunes con los que me encuentro son:
User-Agent
.socketCloseListener
, como se describe en la respuesta de Blender, no es el único lugar donde se crean los errores de colgar.Por ejemplo, encontrado aquí :
Puede 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 concurl
, pero sí obtiene una respuesta en su navegador,User-Agent
es probable que su encabezado esté bloqueado.fuente
Otro caso que vale la pena mencionar (para Linux y OS X) es que si usa una biblioteca como
https
para realizar las solicitudes, o si pasahttps://...
como una URL de la instancia servida localmente, usará un puerto443
que es un puerto privado reservado y usted podría estar terminando enSocket hang up
oECONNREFUSED
errores.En su lugar, use port
3000
, fe y haga unahttp
solicitud.fuente
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 seguía fallando con el mensaje de colgar el socket .
Después de algunas dificultades pude resolver el problema, ya que salió como un error muy, muy simple. Me estaba conectando a la base de datos a través del protocolo HTTPS, pero seguía pasando a mi nanoobjeto un agente keepalive creado como muestran los ejemplos para el uso de esta biblioteca (se basan en algunos valores predeterminados que usan http).
Un simple cambio para usar HttpsAgent hizo el truco:
fuente
Esto me causó problemas, ya que estaba haciendo todo lo que se enumera aquí, pero todavía recibía errores. Resulta que llamar a req.abort () en realidad arroja un error, con un código de ECONNRESET, por lo que en realidad debe detectarlo en su controlador de errores.
fuente
Para
request
usuarios de módulosTenga en cuenta que los tiempos de espera de conexión emiten un
ETIMEDOUT
error y los tiempos de espera de lectura emiten unECONNRESET
error.fuente
Tuve el mismo problema durante la solicitud a algún servidor. En mi caso, configurar cualquier valor para User-Agent en los encabezados en las opciones de solicitud me ayudó.
No es un caso general y depende de la configuración del servidor.
fuente
También la razón puede deberse al uso de
app
instancia de enexpress
lugar deserver
desdeconst server = http.createServer(app)
mientras se crea el socket del servidor.Incorrecto
Correcto
fuente
Realizo desarrollo web (nodo) y Android, y abro el simulador de dispositivo Android Studio y el acoplador juntos, ambos usan el puerto 8601, se quejó de
socket hang up
error, después de cerrar el simulador de dispositivo Android Studio y funciona bien en el lado del nodo. No use el simulador de dispositivo Android Studio y la ventana acoplable juntos.fuente
Recibí un error similar al usar CouchDB en el clúster OCP.
Que debe ser "http", no "https", para conectarse con mi instancia CouchDB. Espero que pueda ser útil para cualquiera que se enfrente a un problema similar.
fuente
En mi caso, fue porque una respuesta de aplicación / json estaba mal formateada (contiene un seguimiento de pila). La respuesta nunca fue enviada al servidor. Fue muy difícil de depurar porque no había registro. Este hilo me ayuda mucho a entender lo que sucede.
fuente
En caso de que esté utilizando node-http-proxy, tenga en cuenta este problema, que provocará un error de bloqueo de socket: https://github.com/nodejitsu/node-http-proxy/issues/180 .
Para la resolución, también en este enlace, simplemente mueva declarando la ruta API (para proxy) dentro de las rutas express antes de express.bodyParser ().
fuente
Encontré este problema ayer ejecutando mi aplicación web y el servidor node.js a través de IntelliJ IDEA 2016.3.6. Todo lo que tenía que hacer era borrar mis cookies y caché en mi navegador Chrome.
fuente
Si está experimentando este error en una conexión https y está sucediendo instantáneamente, podría ser un problema configurar la conexión SSL.
Para mí fue este problema https://github.com/nodejs/node/issues/9845 pero para ti podría ser otra cosa. Si es un problema con el ssl, entonces debería poder reproducirlo con el paquete nodejs tls / ssl solo tratando de conectarse al dominio
fuente
Creo que vale la pena señalar ...
Estaba creando pruebas para las API de Google. Estaba interceptando la solicitud con un servidor improvisado y luego los reenviaba a la API real. Intenté pasar los encabezados en la solicitud, pero algunos encabezados estaban causando un problema con express en el otro extremo.
Es decir, tuve que eliminar
connection
,accept
ycontent-length
encabezados antes de usar el módulo de solicitud para reenviar.fuente
En mi caso, no fue un error, sino un comportamiento esperado para el navegador Chrome. Chrome mantiene viva la conexión de tls (creo que para la velocidad), pero el servidor node.js la detiene después de 2 minutos y obtiene un error.
Si intenta solicitar GET utilizando el navegador de borde, no habrá ningún error en absoluto. Si cierra la ventana de Chrome, recibirá un error de inmediato.
¿Entonces lo que hay que hacer? 1) Puede filtrar estos errores, porque en realidad no son errores. 2) Tal vez hay una mejor solución :)
fuente
Parece que hay un caso adicional aquí, que es que Electron no es fanático del nombre de dominio "localhost". En mi caso, necesitaba cambiar esto:
a esto:
Después de eso, el problema simplemente desapareció.
Esto significa que la resolución DNS (local o remota) también podría estar causando algunos problemas.
fuente
Después de una larga depuración en el código del nodo js, cadena de conexión mongodb, comprobación de CORS, etc., para mí simplemente cambiar a un número de puerto diferente lo
server.listen(port);
hizo funcionar, enpostman
, intente eso también. No hay cambios en laproxy
configuración solo los valores predeterminados.fuente
Este error también puede ocurrir al trabajar con
http.request
, probablemente su solicitud aún no haya finalizado.Ejemplo:
const req = https.request(options, res => {})
Y siempre necesita agregar esta línea:
req.end()
con esta función ordenaremos finalizar el envío de la solicitud.Como en la documentación se dice:
Con http.request () siempre se debe llamar a req.end () para indicar el final de la solicitud, incluso si no se escriben datos en el cuerpo de la solicitud.
fuente