Узел js ECONNRESET
я запускаю приложение Express js с помощью socket.io для чата
webapp и я получаю следующую ошибку случайным образом около 5 раз во время
24ч. Процесс узел, завернутый в навсегда и он перезапускается
сама сразу же.
проблема в том, что перезапуск express выбивает моих пользователей из своих комнат
и никто этого не хочет.
веб-сервер определяется на основе графических интерфейсов. Нет проблем со стабильностью сокета, просто используя websockets и flashsockets транспорты. Я не могу воспроизвести это нарочно.
это ошибка с узлом v0. 10. 11:
events.js:72
throw er; // Unhandled 'error' event
^
Error: read ECONNRESET //alternatively it s a '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
EDIT (2013-07-22)
добавлены оба socket.io обработчик ошибок клиента и обработчик неперехваченных исключений. Кажется, что это один ловит ошибку:
process.on('uncaughtException', function (err) {
console.error(err.stack);
console.log("Node NOT Exiting...");
});
так что я подозреваю, что это не a socket.io проблема, но http-запрос на другой сервер, который я делаю, или соединение mysql/redis. Проблема в том, что стек ошибок не помогает мне определить мою проблему с кодом. Вот вывод журнала:
Error: read ECONNRESET
at errnoException (net.js:900:11)
at TCP.onread (net.js:555:19)
как я узнаю, что вызывает это? Как мне получить больше от ошибки?
хорошо, не очень многословно, но вот stacktrace с "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] ] } }
здесь я служу файл политики флэш-сокета:
net = require("net")
net.createServer( (socket) =>
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("<cross-domain-policy>n")
socket.write("<allow-access-from domain="*" to-ports="*"/>n")
socket.write("</cross-domain-policy>n")
socket.end()
).listen(843)
может ли это быть причиной?
11 ответов:
Вы, наверное, уже догадались: это ошибка подключения.
"ECONNRESET" означает, что другая сторона разговора TCP резко закрыла свой конец соединения. Это, скорее всего, связано с одной или несколькими ошибками протокола приложения. Вы можете посмотреть журналы сервера API, чтобы узнать, жалуется ли он на что-то.
но так как вы также ищете способ проверить ошибку и потенциально отладить проблему, вы должны взглянуть на "как отладить сокет повесить ошибку в NodeJS?" который был размещен в stackoverflow в отношении аналогичного вопроса.
быстрое и грязное решение для развития:
использовать longjohn, вы получаете длинные трассировки стека, которые будут содержать асинхронные операции.
чистота и правильное решение: Технически, в узле, когда вы испускают
'error'событие и никто его не слушает, он бросит. Чтобы его не кинуть, поставьте на него слушателя и справьтесь с ним сами. Таким образом, вы можете зарегистрировать ошибку с дополнительной информацией.чтобы иметь один прослушиватель для группы вызовов, вы можете использовать Домены а также поймать другие ошибки во время выполнения. Убедитесь, что каждая асинхронная операция, связанная с http (сервер / клиент), находится в разных домен контексте по сравнению с другими частями кода, домен будет автоматически слушайте
errorсобытия и будет распространять его на свой собственный обработчик. Таким образом, вы только слушаете этот обработчик и получаете данные об ошибке. вы также получаете дополнительную информацию бесплатно.EDIT (2013-07-22)
Как я уже писал выше:
"ECONNRESET" означает, что другая сторона разговора TCP резко закрыла свой конец соединения. Это, скорее всего, связано с одним или несколькими протоколами приложений ошибки. Вы можете посмотреть журналы сервера API, чтобы узнать, жалуется ли он на что-то.
что также может быть так: в случайные моменты времени другая сторона перегружена и просто убивает соединение в результате. Если это так, зависит от того, к чему именно вы подключаетесь...
но одно точно: у вас действительно есть ошибка чтения на вашем TCP-соединении, которая вызывает исключение. Вы можете увидеть это, посмотрев на код ошибки, который вы опубликовали в своем редактировании, который подтвердить это.
простой tcp-сервер, который у меня был для обслуживания файла политики flash, вызывал это. Теперь я могу поймать ошибку с помощью обработчика:
# 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("<cross-domain-policy>\n") socket.write("<allow-access-from domain=\"*\" to-ports=\"*\"/>\n") socket.write("</cross-domain-policy>\n") socket.end() ).listen(843)
У меня была аналогичная проблема, когда приложения начали ошибаться после обновления узла. Я считаю, что это можно проследить до выпуска узла v0.9. 10 этот элемент:
- net: не подавляйте ECONNRESET (Ben Noordhuis)
предыдущие версии не будут ошибаться при прерываниях от клиента. Перерыв в соединении от клиента вызывает ошибку ECONNRESET в узле. Я считаю, что это предназначенная функциональность для узла, поэтому исправление (по крайней мере для меня) было обработайте ошибку, которую, я считаю, вы сделали в неперехваченных исключениях. Хотя я справляюсь с этим в сети.обработчик сокетов.
вы можете продемонстрировать это:
сделайте простой сервер сокетов и получите узел v0.9.9 и v0.9.10.
require('net') .createServer( function(socket) { // no nothing }) .listen(21, function() { console.log('Socket ON') })запустите его с помощью v0.9.9, а затем попытайтесь FTP на этот сервер. Я использую FTP и порт 21 только потому, что я нахожусь в Windows и имею FTP-клиент, но нет клиента telnet.
затем со стороны клиента, просто сломать соединение. (Я просто делаю Ctrl-C)
вы не должны видеть ошибки при использовании узла v0.9.9, и ошибки при использовании узла V.0.9.10 и выше.
в производство, я использую В. 0.10. что-то и это все равно дает ошибку. Опять же, я думаю, что это предназначено, и решение заключается в обработке ошибки в вашем коде.
я столкнулся с той же проблемой, но я смягчил его, поместив:
server.timeout = 0;до
server.listen.server- это HTTP-сервер здесь. Время ожидания по умолчанию составляет 2 минуты на документация API.
была та же проблема сегодня. После некоторых исследований я нашел очень полезным
--abort-on-uncaught-exceptionузел.вариант с JS. Он не только обеспечивает гораздо более подробную и полезную трассировку стека ошибок, но и сохраняет основной файл при сбое приложения, позволяя дальнейшую отладку.
Да, ваша подача файла политики определенно может вызвать сбой.
чтобы повторить, просто добавьте задержку в свой код:
net.createServer( function(socket) { for(i=0; i<1000000000; i++); socket.write("<?xml version=\"1.0\"?>\n") …и
telnetдля подключения к порту. Если вы отключите telnet до истечения срока задержки, вы получите сбой (неперехваченное исключение), когда сокет.запись выдает ошибку.чтобы избежать сбоя здесь, просто добавьте обработчик ошибок перед чтением / записью сокета:
net.createServer( function(socket) { for(i=0; i<1000000000; i++); socket.on('error', function() { console.log("error"); }); socket.write("<?xml version=\"1.0\"?>\n")при попытке выше отключитесь, вы просто получите сообщение журнала вместо сбоя.
и когда вы закончите, не забудьте убрать задержку.
другой возможный случай (но редкий) может быть, если у вас есть связь между серверами и установить
server.maxConnectionsдо очень низкого значения.в ядре узла lib net.js он будет вызывать
clientHandle.close()что также вызовет ошибку ECONNRESET:if (self.maxConnections && self._connections >= self.maxConnections) { clientHandle.close(); // causes ECONNRESET on the other end return; }
Я решил проблему просто подключение к другой сети. Это одна из возможных проблем.
Как указывалось выше, ECONNRESET означает, что разговор TCP резко закрыл свой конец соединения.
подключение к сети может блокировать подключение к некоторым серверам. В моем случае я пытался подключиться к mLab ( cloud database service, в котором размещаются базы данных MongoDB). И мой интернет-провайдер блокирует его.
Я также получаю ошибку ECONNRESET во время моей разработки, так как я решаю ее с помощью не используя nodemon для запуска моего сервера, просто используйте
"node server.js"для запуска моего сервера исправлена моя проблема.это странно, но это сработало для меня, теперь я никогда не вижу ошибку ECONNRESET снова.
У меня тоже была эта ошибка, и я смог решить ее после нескольких дней отладки и анализа:
мое решение
для меня VirtualBox (для Докера) была проблема. У меня была настроена переадресация портов на моей виртуальной машине, и ошибка произошла только на переадресованном порту.
общие выводы
следующие наблюдения могут сэкономить Вам дни работы, которые я должен был инвестировать:
- для меня проблема возникла только при соединениях с localhost localhost на одном порту. - >проверьте изменение любой из этих констант решает проблему.
- для меня проблема только на моей машине -пусть кто-нибудь попробует его.
- для меня проблема возникла только через некоторое время и не может быть воспроизведена надежно
- моя проблема не может быть проверена с помощью любого из узлов или инструментов expresses (debug -). - > не тратьте время на это
- > выяснить, если что-то возится с вашим сеть (- настройки), такие как виртуальные машины, брандмауэры и т. д. это, вероятно, является причиной проблемы.
попробуйте добавить эти параметры socket.io:
const options = { transports: ['websocket'], pingTimeout: 3000, pingInterval: 5000 };Я надеюсь, что это поможет вам !
Comments