Socket.ioでnode.jsを使用して、TCPソケットによって提供される文字データにWebページにアクセスできるようにします。node.jsはまったく新しいです。
User---->Webページ< ソケット。 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スタックはnode.jsにECONNREFUSEDを返します-これは完全に予期されたものであり、適切に処理する必要があります。
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はまだソケットエラーで呼び出されています -上記のコードで行ったように、「エラー」イベントのハンドラーを追加することをお勧めします。これはまさに私がそれを動作させたい方法です...それは(私にとって)そうではないことを除いて、私のプログラムはECONNREFUSEDをトラップしません。
私はRTFMを試みましたが、node.jsのドキュメント http://nodejs.org/api/net.html#net_event_error_1 は実際には「エラー」イベントがあることを示唆していますが、使い方の手がかり。
他の同様のSO投稿( Node.js Error:connect ECONNREFUSED など)への回答は、グローバルなキャッチされていない例外ハンドラーにアドバイスしますが、これは私にとっては貧弱なソリューションのようです。これは、悪いコードが原因で例外をスローするプログラムではなく、正常に動作しています-設計どおりに外部障害を処理することになっています。
そう
ああ、そして:
$ node -v
v0.10.31
私は次のコードを実行しました:
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ソケットを介してWebページに送信されます。
webSocket.emit('warning', error);
これを修正するために私が見つけた唯一の方法は、ドメインにネットのものをラップすることです:
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) => {
...
});
});
});
ドメインエラーは、無効なホストなど、ネットクライアントが作成される前に発生するエラー状態をキャプチャします。