Nodo js ECONNRESET

Estoy ejecutando una aplicación Express js con socket.io para una aplicación de chat y obtengo el siguiente error aleatoriamente alrededor de 5 veces durante 24 horas. El proceso del nodo está envuelto para siempre y se reinicia inmediatamente.

El problema es que al reiniciar Express los patadas salen de sus habitaciones y nadie quiere eso.

El servidor web es proxy por HAProxy. No hay problemas de estabilidad del socket, solo se usan websockets y transportes de tomas de stream. No puedo reproducir esto a propósito.

Este es el error con el nodo v0.10.11:

events.js:72 throw er; // Unhandled 'error' event ^ Error: read ECONNRESET //alternatively it sa 'write' at errnoException (net.js:900:11) at TCP.onread (net.js:555:19) error: Forever detected script exited with code: 8 error: Forever restarting script for 2 time 

EDITAR (22-07-2013)

Se agregó el controlador de error del cliente socket.io y el controlador de excepciones no detectadas. Parece que este capta el error:

 process.on('uncaughtException', function (err) { console.error(err.stack); console.log("Node NOT Exiting..."); }); 

Así que sospecho que no es un problema de socket.io sino una solicitud http a otro servidor que hago o una conexión mysql / redis. El problema es que la stack de errores no me ayuda a identificar mi problema de código. Aquí está la salida de registro:

 Error: read ECONNRESET at errnoException (net.js:900:11) at TCP.onread (net.js:555:19) 

¿Cómo sé qué causa esto? ¿Cómo puedo sacar más provecho del error?

Ok, no muy detallado, pero aquí está la stacktrace con “longjohn”:

 Exception caught: Error ECONNRESET { [Error: read ECONNRESET] code: 'ECONNRESET', errno: 'ECONNRESET', syscall: 'read', __cached_trace__: [ { receiver: [Object], fun: [Function: errnoException], pos: 22930 }, { receiver: [Object], fun: [Function: onread], pos: 14545 }, {}, { receiver: [Object], fun: [Function: fireErrorCallbacks], pos: 11672 }, { receiver: [Object], fun: [Function], pos: 12329 }, { receiver: [Object], fun: [Function: onread], pos: 14536 } ], __previous__: { [Error] id: 1061835, location: 'fireErrorCallbacks (net.js:439)', __location__: 'process.nextTick', __previous__: null, __trace_count__: 1, __cached_trace__: [ [Object], [Object], [Object] ] } } 

Aquí sirvo el archivo de política de socket flash:

 net = require("net") net.createServer( (socket) => socket.write("\n") socket.write("\n") socket.write("\n") socket.write("\n") socket.write("\n") socket.end() ).listen(843) 

¿Puede ser esta la causa?

Ya lo habrás adivinado: es un error de conexión.

“ECONNRESET” significa que el otro lado de la conversación TCP cerró abruptamente el final de la conexión. Esto probablemente se deba a uno o más errores de protocolo de aplicación. Puede consultar los registros del servidor API para ver si se queja de algo.

Pero dado que también está buscando una forma de verificar el error y posiblemente depurar el problema, debería consultar ” Cómo depurar un error de colgado de socket en NodeJS? “ Que se publicó en stackoverflow en relación con una pregunta similar.

Solución rápida y sucia para el desarrollo :

Usa longjohn , obtienes largas trazas de stack que contendrán las operaciones asincrónicas.

Solución limpia y correcta : Técnicamente, en el nodo, cada vez que se emite un evento de 'error' y nadie lo escucha, se lanzará . Para que no se arroje, coloque un oyente y hágalo usted mismo. De esta forma puede registrar el error con más información.

Para tener un oyente para un grupo de llamadas, puede usar dominios y también detectar otros errores en el tiempo de ejecución. Asegúrese de que cada operación asíncrona relacionada con http (Servidor / Cliente) se encuentre en un contexto de dominio diferente en comparación con las otras partes del código, el dominio escuchará automáticamente los eventos de error y lo propagará a su propio controlador. Entonces solo escuchas a ese controlador y obtienes los datos de error. También obtienes más información gratis.

EDITAR (22-07-2013)

Como escribí arriba:

“ECONNRESET” significa que el otro lado de la conversación TCP cerró abruptamente el final de la conexión. Esto probablemente se deba a uno o más errores de protocolo de aplicación. Puede consultar los registros del servidor API para ver si se queja de algo.

Lo que también podría ser el caso: en momentos aleatorios, el otro lado está sobrecargado y simplemente mata la conexión como resultado. Si ese es el caso, depende de a qué se conecta exactamente …

Pero una cosa es segura: de hecho tiene un error de lectura en su conexión TCP que causa la excepción. Puedes verlo mirando el código de error que publicaste en tu edición, que lo confirma.

Un simple servidor tcp que tenía para servir el archivo de política flash estaba causando esto. Ahora puedo detectar el error usando un controlador:

 # serving the flash policy file net = require("net") net.createServer((socket) => //just added socket.on("error", (err) => console.log("Caught flash policy server socket error: ") console.log(err.stack) ) socket.write("< ?xml version=\"1.0\"?>\n") socket.write("< !DOCTYPE cross-domain-policy SYSTEM \"http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd\">\n") socket.write("\n") socket.write("\n") socket.write("\n") socket.end() ).listen(843) 

Tuve un problema similar cuando las aplicaciones comenzaron a fallar después de una actualización de Node. Creo que esto se remonta a la versión de nodo v0.9.10 de este elemento:

  • neto: no suprimir ECONNRESET (Ben Noordhuis)

Las versiones anteriores no generarían errores en las interrupciones del cliente. Un corte en la conexión del cliente arroja el error ECONNRESET en el nodo. Creo que esta es la funcionalidad prevista para Node, por lo que la solución (al menos para mí) fue manejar el error, lo que creo que hiciste en excepciones no detectadas. Aunque lo manejo en el controlador net.socket.

Puedes demostrar esto:

Cree un servidor de socket simple y obtenga el nodo v0.9.9 y v0.9.10.

 require('net') .createServer( function(socket) { // no nothing }) .listen(21, function() { console.log('Socket ON') }) 

Enciéndalo usando v0.9.9 y luego intente FTP a este servidor. Estoy usando FTP y el puerto 21 solo porque estoy en Windows y tengo un cliente de FTP, pero no tengo un cliente de telnet a mano.

Luego, desde el lado del cliente, solo rompe la conexión. (Solo estoy haciendo Ctrl-C)

Debería ver SIN ERROR al usar el Nodo v0.9.9, y ERROR al usar el Nodo v.0.9.10 y superior.

En producción, utilizo v.0.10. algo y todavía da el error. De nuevo, creo que esto es intencionado y la solución es manejar el error en su código.

Tuve el mismo problema hoy. Después de algunas investigaciones encontré una --abort-on-uncaught-exception muy útil --abort-on-uncaught-exception node.js. No solo proporciona un seguimiento de la stack de errores mucho más detallado y útil, sino que también guarda el archivo central en el locking de la aplicación, lo que permite una mayor depuración.

Estaba enfrentando el mismo problema pero lo mitigué colocando:

 server.timeout = 0; 

antes de server.listen . server es un servidor HTTP aquí. El tiempo de espera predeterminado es de 2 minutos según la documentación de la API .

Sí, su publicación del archivo de política definitivamente puede causar el locking.

Para repetir, simplemente agrega un retraso a tu código:

 net.createServer( function(socket) { for(i=0; i<1000000000; i++); socket.write("< ?xml version=\"1.0\"?>\n") … 

… y use telnet para conectarse al puerto. Si desconecta Telnet antes de que el retraso haya expirado, obtendrá un locking (excepción no detectada) cuando socket.write arroja un error.

Para evitar el locking aquí, simplemente agregue un controlador de errores antes de leer / escribir el socket:

 net.createServer( function(socket) { for(i=0; i<1000000000; i++); socket.on('error', function() { console.log("error"); }); socket.write("< ?xml version=\"1.0\"?>\n") 

Cuando pruebe la desconexión anterior, obtendrá un mensaje de registro en lugar de un locking.

Y cuando haya terminado, recuerde eliminar la demora.

Otro posible caso (pero raro) podría ser si tiene comunicaciones de servidor a servidor y ha establecido server.maxConnections a un valor muy bajo.

En core lib net.js del nodo llamará a clientHandle.close() que también causará el error ECONNRESET:

 if (self.maxConnections && self._connections >= self.maxConnections) { clientHandle.close(); // causes ECONNRESET on the other end return; } 

Resolví el problema simplemente conectándome a una red diferente . Ese es uno de los posibles problemas.

Como se discutió anteriormente, ECONNRESET significa que la conversación TCP cerró bruscamente el final de la conexión.

Su conexión a Internet podría estar bloqueando su conexión a algunos servidores. En mi caso, estaba tratando de conectarme a mLab (servicio de base de datos en la nube que aloja las bases de datos MongoDB). Y mi ISP lo está bloqueando.

También recibo el error ECONNRESET durante mi desarrollo, la forma en que lo resuelvo es no usar nodemon para iniciar mi servidor, solo use "node server.js" para que mi servidor solucione mi problema.

Es extraño, pero funcionó para mí, ahora nunca más veo el error ECONNRESET.

También tuve este error y pude resolverlo después de días de depuración y análisis:

mi solución

Para mí, VirtualBox (para Docker) fue el problema. Tuve el reenvío de puertos configurado en mi VM y el error solo ocurrió en el puerto reenviado.

conclusiones generales

Las siguientes observaciones pueden ahorrarle días de trabajo que tuve que invertir:

  • Para mí, el problema solo se produjo en las conexiones de localhost a localhost en un puerto. -> comprobar el cambio de cualquiera de estas constantes resuelve el problema.
  • Para mí, el problema solo ocurrió en mi máquina -> deje que alguien más lo intente.
  • Para mí, el problema solo ocurrió después de un tiempo y no se pudo reproducir confiablemente
  • Mi problema no pudo ser inspeccionado con ninguno de los nodos ni con las herramientas de expresión (depuración). -> no pierdas el tiempo en esto

-> averiguar si algo está jugando con su red (ajustes), como máquinas virtuales, cortafuegos, etc., esta es probablemente la causa del problema.

Intente agregar estas opciones a socket.io:

 const options = { transports: ['websocket'], pingTimeout: 3000, pingInterval: 5000 }; 

Espero que esto ayude !