30

node.js と socket.io を使用して、Web ページが TCP ソケットによって提供される文字データにアクセスできるようにしています。私はnode.jsを初めて使用します。

ユーザー ----> Web ページ <--(socket.io)--> node.js <--(TCP)--> TCP サーバー

コードは非常に簡潔です。

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 - は、上記のコードで行ったように、「エラー」イベントのハンドラーを追加することを提案しています。これはまさに私が望んでいる方法です...そうでないことを除いて(私にとっては)、私のプログラムはECONNREFUSEDをトラップしません。

私は RTFM を試みましたが、http://nodejs.org/api/net.html#net_event_error_1 の node.js ドキュメント、実際に「エラー」イベントがあることを示唆していますが、それを使用する方法についてはほとんど手がかりがありません。

他の同様の SO 投稿 ( Node.js Error: connect ECONNREFUSEDなど) への回答は、キャッチされていないグローバルな例外ハンドラーをアドバイスしますが、これは私には不十分な解決策のようです。これは私のプログラムが悪いコードのために例外をスローしたのではなく、正常に動作しています。設計どおりに外部エラーを処理するはずです。

そう

  • 私はこれに正しい方法で取り組んでいますか?(これが初心者のエラーであることを認めてうれしいです)
  • 私がやりたいことをすることは可能ですか?

ああ、そして:

$ node -v
v0.10.31
4

2 に答える 2

32

次のコードを実行しました。

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

「エラー」イベントは特殊であり、どこかで処理する必要があります (そうでない場合、プロセスは終了します)。

イベントの名前を 'problem' または 'warning' に変更するだけで、エラー オブジェクト全体が socket.io ソケットを介して Web ページに送信されます。

webSocket.emit('warning', error);
于 2014-09-15T11:30:31.567 に答える