2014-09-15 2 views
13

Я использую node.js с socket.io, чтобы предоставить моей веб-странице доступ к символьным данным, обслуживаемым сокетом TCP. Я довольно новичок в node.js.node.js - обработка ошибки сокета TCP ECONNREFUSED

пользователя ---->Web Page < - (socket.io) ->node.js < - (TCP) ->TCP Server

код милостиво краток:

io.on('connection', function (webSocket) { 
    tcpConnection = net.connect(5558, 'localhost', function() {}); 

    tcpConnection.on('error', function(error) { 
     webSocket.emit('error', error); 
     tcpConnection.close(); 
    }); 

    tcpConnection.on('data', function(tcpData) { 
     webSocket.emit('data', { data: String.fromCharCode.apply(null, new Uint8Array(tcpData))}); 
    }); 
}); 

это все прекрасно работает в обычном случае, но я не могу гарантировать, что сервер TCP будет там все время. Когда это не так, стек TCP возвращает ECONNREFUSED на node.js - это полностью ожидаемо, и мне нужно обработать его изящно. В настоящее время я вижу:

events.js:72 
    throw er; // Unhandled 'error' event 
     ^
Error: connect ECONNREFUSED 
    at errnoException (net.js:904:11) 
    at Object.afterConnect [as oncomplete] (net.js:895:19) 

... и весь процесс завершается.

Я много искал для этого решения; большинство хитов, похоже, от программистов, спрашивающих, почему ECONNREFUSED принимается в первую очередь, - а совет - просто убедиться, что TCP-сервер доступен. Никаких обсуждений об ошибках обработки.

Этот пост - Node.js connectListener still called on socket error - предлагает добавить обработчик для события 'error', как я сделал в коде выше. Это именно то, как я хотел бы, чтобы он работал ... кроме этого нет (для меня), моя программа не захватывает ECONNREFUSED.

Я пробовал RTFM, а node.js docs на http://nodejs.org/api/net.html#net_event_error_1 предполагают, что действительно есть событие «error», но мало подсказывайте, как его использовать.

Ответы на другие подобные сообщения SO (такие как Node.js Error: connect ECONNREFUSED) советуют глобальный неперехваченный обработчик исключений, но это кажется плохим решением для меня. Это не моя программа, бросающая исключение из-за плохого кода, он работает нормально - предполагается, что он обрабатывает внешние сбои, как это было разработано.

Так

  • Am I приближается это в правильном направлении? (с удовольствием признаю, что это ошибка новичков)
  • Можно ли делать то, что я хочу делать, и если да, то как?

О, и:

$ node -v 
v0.10.31 
+0

проблема, скорее всего, в: 'TCPConnection = сеть. connect (5558, 'localhost', function() {}); 'невозможно подключиться. В коде мало что можно сделать, вам нужно убедиться, что порт 5558 на локальном хосте фактически открыт и прослушивается. – alandarev

+0

Дело в том, что я не могу этого гарантировать. Тот факт, что он на localhost является красной селедкой, - представьте, что он был на каком-то удаленном сервере, где связь была не такой надежной, как localhost. Каждый другой язык программирования позволяет изящно улавливать ошибку (например, connect() в наборах C errno, connect (SocketAddress) в Java выдает исключение IOException и т. Д. И т. Д.). –

ответ

14

Я побежал следующий код:

var net = require('net'); 

var client = net.connect(5558, 'localhost', function() { 
    console.log("bla"); 
}); 
client.on('error', function(ex) { 
    console.log("handled error"); 
    console.log(ex); 
}); 

Как я не имею 5558 разомкнут, выход был:

$ node test.js 
handled error 
{ [Error: connect ECONNREFUSED] 
    code: 'ECONNREFUSED', 
    errno: 'ECONNREFUSED', 
    syscall: 'connect' } 

Это доказывает, что ошибка обрабатывается просто отлично ... предполагая, что ошибка происходит в другом месте.

Как обсуждалось в другой ответ, проблема на самом деле эта линия:

webSocket.emit('error', error); 

«ошибка» событие особенное и должно быть обработано где-то (если это не так, то процесс заканчивается).

Просто переименовании событие «проблемы» или результаты «предупреждение» в целом объекта ошибки передается обратно через Socket.io гнездо до веб-страницы:

webSocket.emit('warning', error); 
+0

Вы правы, это работает очень хорошо - и помог мне отследить реальную проблему (см. Мой ответ на мой собственный вопрос). Благодаря! –

+0

На самом деле, я хотел знать hw, чтобы обойти эту ошибку? разместил вопрос здесь: http://stackoverflow.com/questions/32428693/net-connect-reconnecting-tcp-net-connects-yields-connect-econnrefused – user2290820

2

ОК, немного неловко, его оказывается, что проблема на самом деле эта линия:

webSocket.emit('error', error); 

Мой намерение было:

  • (например, ECONNREFUSED)
  • «перебросить» их через сокет socket.io на веб-страницу клиента
  • обрабатывать их каким-то образом на веб-странице (хотя, конечно, с некоторой переработкой/санитацией в каким-либо образом для отображения пользователю)

Однако событие 'error' является особенным и должно быть обработано где-то (чего я не делал - отсюда завершение процесса).

Просто переименовании событие результаты «проблема» в целом объекта ошибки передается обратно через гнездо Socket.io до веб-страницы:

webSocket.emit('problem', error); 
+0

Я бы переименовал '' problem'' в '' warning'', как слово * проблема * не является техническим. Кроме того, он честно находится на пограничной линии, чтобы грубо получить и использовать помощь, а затем просто отправить свой собственный ответ. Посмотрите: http://stackoverflow.com/tour – alandarev

+0

Понял. Ваша помощь помогла мне решить проблему (за что я благодарен, и именно поэтому я поблагодарил вас за это). Как бы то ни было, я прочитал документы SO etiquette о том, что делать в этой ситуации, но я не видел конкретного упоминания (с удовольствием исправлялся): проблема была на самом деле ошибкой, вызванной несвязанным кодом, несвязанной проблемой (неправильное использование событие «error»). Я был бы рад отметить ваш ответ как правильный, но в настоящее время он фактически не содержит ответа на исходную проблему, поэтому я не могу его принять. Если вы хотите отредактировать его так, чтобы он это сделал, я это рассмотрю! –

+0

Спасибо за ваше подтверждение. Делайте, как вы находите, лучше для вас. Мне было неправильно начинать драму в первую очередь. – alandarev

Смежные вопросы