it-swarm.com.de

node.js - Handhabung TCP Socket-Fehler ECONNREFUSED

Ich verwende node.js mit socket.io, um meiner Webseite Zugriff auf Zeichendaten zu gewähren, die von einem TCP - Socket bedient werden. Ich bin ganz neu bei node.js.

Benutzer ----> Webseite <- (socket.io) -> node.js <- (TCP) -> TCP Server

Der Code ist barmherzig kurz:

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))});
    });
});

Im Normalfall funktioniert alles einwandfrei, aber ich kann nicht garantieren, dass der TCP -Server immer da ist. Wenn dies nicht der Fall ist, gibt der TCP - Stack ECONNREFUSED an node.js zurück. Dies ist durchaus zu erwarten und ich muss es ordentlich behandeln. Derzeit sehe ich:

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)

... und der ganze Prozess endet.

Ich habe viel nach Lösungen dafür gesucht; Die meisten Hits scheinen von Programmierern zu sein, die fragen, warum ECONNREFUSED überhaupt erst empfangen wird - und es wird lediglich empfohlen, sicherzustellen, dass der TCP -Server verfügbar ist. Keine Besprechung der Behandlung von Fehlerfällen.

In diesem post - Node.js connectListener wird der Socket error - noch aufgerufen, und es wird vorgeschlagen, einen Handler für das 'error' - Ereignis hinzuzufügen, wie ich es im obigen Code getan habe. Genau so möchte ich, dass es funktioniert ... außer wenn dies nicht der Fall ist (für mich), fängt mein Programm ECONNREFUSED nicht an.

Ich habe RTFM ausprobiert, und die node.js -Dokumente unter http://nodejs.org/api/net.html#net_event_error_1 lassen darauf schließen, dass es tatsächlich ein 'error' -Ereignis gibt - aber geben Sie wenig Ahnung, wie benutze es.

Antworten auf andere ähnliche SO - Posts (z. B. Node.js: Fehler: connect ECONNREFUSED ) weisen auf einen globalen nicht erfassten Ausnahmebehandler hin. Dies scheint mir jedoch eine schlechte Lösung zu sein. Dies ist nicht mein Programm, das eine Ausnahme aufgrund fehlerhaften Codes auslöst, es funktioniert einwandfrei - es soll externe Fehler so behandeln, wie es vorgesehen ist.

So

  • Nehme ich das richtig an? (froh zuzugeben, das ist ein Anfängerfehler)
  • Kann ich tun, was ich will, und wenn ja, wie?

Oh und:

$ node -v
v0.10.31
15
Chris Mead

Ich habe den folgenden Code ausgeführt:

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);
});

Da ich keine 5558 geöffnet habe, war die Ausgabe:

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

Dies beweist, dass der Fehler gut gehandhabt wird, was darauf hindeutet, dass der Fehler anderswo auftritt.

Wie in einer anderen Antwort beschrieben, ist das Problem eigentlich diese Zeile:

webSocket.emit('error', error);

Das Fehlerereignis ist etwas Besonderes und muss irgendwo behandelt werden (andernfalls wird der Prozess beendet).

Wenn Sie das Ereignis einfach in "Problem" oder "Warnung" umbenennen, wird das gesamte Fehlerobjekt über den Socket.io bis zur Webseite zurückgesendet:

webSocket.emit('warning', error);
16
alandarev

Die einzige Möglichkeit, dies zu beheben, besteht darin, das Netzmaterial in eine Domäne einzuwickeln:

const domain = require('domain');
const net = require('net');

const d = domain.create();

d.on('error', (domainErr) => {
    console.log(domainErr.message);
});

d.run(() => {
    const client = net.createConnection(options, () => {

        client.on('error', (err) => {
            throw err;
        });
        client.write(...);
        client.on('data', (data) => {
            ...
        });
    });
});

Der Domänenfehler erfasst Fehlerbedingungen, die vor dem Erstellen des Netzclients auftreten, z. B. ein ungültiger Host.

Siehe auch: https://nodejs.org/api/domain.html

0
Jan Bauer