0

node.js でストリームについて学習しようとしています!

サーバー.js

var net = require("net");

var server = net.createServer(function(conn) {

  conn.write("welcome!");

  # echo the user input!
  conn.pipe(conn);
});

server.listen("1111", function() {
  console.log("port 1111 opened");
});

telnet テスト

サーバーは現在、ユーザーの入力をエコーし​​ています

$ telnet localhost 1111
welcome!
hello
hello

希望の出力

{}サーバー側でストリームを処理する場所/方法を示すために、エコーバックする前にユーザーの入力をラップしたいと思います

$ telnet localhost 1111
welcome!
hello
{hello}
4

3 に答える 3

3

これは基本的に、要求した正確な出力を実現します。

var net = require('net');

var server = net.createServer(function(c) {
    c.setEncoding('utf8');
    c.on('data', function(d) {
        c.write('{' + d.trim() + '}\n');
    });
});

server.listen(9871);

まず、 に注意を向けさせてくださいc.setEncoding('utf8')。これにより、受信バッファを utf8 空間の文字列に自動的に変換するフラグが接続に設定されます。これはあなたの例ではうまくいきますが、ソケット間のパフォーマンスを向上させるには、バッファ操作を実行する方がよいことに注意してください。

の全体をシミュレートするに.pipe()は、もう少しコードが必要です。

.pipe()は、Streamプロトタイプのメソッドで、 にありlib/stream.jsます。ファイルを見ると、上に示したものよりもかなり多くのコードが表示されます。デモンストレーションのために、ここに抜粋があります:

function ondata(chunk) {
  if (dest.writable) {
      if (false === dest.write(chunk) && source.pause) {
          source.pause();
      }
  }
}

source.on('data', ondata);

最初に、宛先が書き込み可能かどうかがチェックされます。そうでない場合、データの書き込みを試みる理由はありません。次に かどうかを確認しますdest.write === false。ドキュメントから:

[.write] は、データ全体がカーネル バッファーに正常にフラッシュされた場合に true を返します。データの全部または一部がユーザー メモリのキューに入れられた場合は、false を返します。

ストリームは v8 メモリ空間の外のカーネル空間に存在するため、(単にノード アプリをクラッシュさせるのではなく) メモリをいっぱいにしてマシンをクラッシュさせる可能性があります。したがって、メッセージが排出されたかどうかを確認することは、安全防止メカニズムです。排出が完了していない場合、ソースはdrainイベントが発行されるまで一時停止されます。排水イベントは次のとおりです。

function ondrain() {
    if (source.readable && source.resume) {
        source.resume();
    }
}

dest.on('drain', ondrain);

がエラーを処理する方法や、独自のイベント エミッターをクリーンアップする方法.pipe()など、カバーできることはまだまだありますが、基本的なことはカバーできたと思います。

注:大きな文字列を送信する場合、複数のパケットで送信される可能性があります。このため、次のようなことを行う必要がある場合があります。

var net = require('net');

var server = net.createServer(function(c) {
    var tmp = '';
    c.setEncoding('utf8');
    c.on('data', function(d) {
        if (d.charCodeAt(d.length - 1) !== 10) {
            tmp += d;
        } else {
            c.write('{' + tmp + d.trim() + '}\n');
            tmp = '';
        }
    });
});

server.listen(9871);

ここでは、文字列が改行文字 ( \n、または ASCII 文字コード 10) で終了するという仮定を使用します。メッセージの最後をチェックして、これに該当するかどうかを確認します。そうでない場合は、改行文字が受信されるまで、接続からのメッセージを一時的に保存します。

これはあなたのアプリケーションでは問題にならないかもしれませんが、注意する価値があると思います.

于 2012-09-26T18:06:01.207 に答える
1

あなたは次のようなことをすることができます

conn.on 'data', (d) ->
  conn.write "{#{d}}"

.pipeメソッドは基本的に、入力ストリームのデータイベントをアタッチして出力ストリームに書き込むだけです。

于 2012-09-26T18:01:35.070 に答える
0

実際に net() についてはよくわかりませんが、http に非常に似ていると思います。

http.createServer(function (req, res) {


        res.writeHead(200, {'Content-Type': 'text/event-stream'});
        http.get(options, function(resp){
            resp.on('data', function(chunk){
                res.write("event: meetup\n");
                res.write("data: "+chunk.toString()+"\n\n");
            });
        }).on("error", function(e){
            console.log("Got error: " + e.message);
        });
});

https://github.com/chovy/nodejs-stream

于 2012-09-26T18:08:19.780 に答える