web-dev-qa-db-ja.com

Node.jsネットでpipe()を使用する

net モジュールのNode.jsのいくつかの例で示されているpipe関数に頭を包むのに問題があります。

var net = require('net');

var server = net.createServer(function (socket) {
  socket.write('Echo server\r\n');
  socket.pipe(socket);
});

誰もがこれがどのように機能し、なぜそれが必要なのか説明を提供できますか?

63
Nick Parsons

pipe()関数は、読み取り可能ストリームが利用可能になったときにデータを読み取り、書き込み可能な宛先ストリームに書き込みます。

ドキュメントの例は、受信したものを送信するサーバーであるエコーサーバーです。 socketオブジェクトは、読み取りと書き込みの両方のストリームインターフェイスを実装するため、受信したデータをソケットに書き戻します。

これは、イベントリスナーを使用してpipe()メソッドを使用するのと同等です。

var net = require('net');
net.createServer(function (socket) {
  socket.write('Echo server\r\n');
  socket.on('data', function(chunk) {
    socket.write(chunk);
  });
  socket.on('end', socket.end);
});
92
hexacyanide

pipe()は、Unixパイプのように、読み取り可能なストリームから読み取り、書き込み可能なストリームに書き込みます。途中でエラー、ファイルの終わり、一方が遅れるなどのすべての「合理的な」ことを行います。特定の例は、socketが読み取りと書き込みの両方であるため、やや混乱します。

わかりやすい例は このSO質問 で、httpリクエストから読み取り、httpレスポンスに書き込みます。

3
user949300

次のリクエストハンドラーを検討してください

var server = http.createServer(function(req, res){
     console.log('Request for ' + req.url + ' by method ' + req.method);
    if(req.method == 'GET'){
        var fileurl;
        if(req.url == '/')fileurl = '/index.html';
        else {
            fileurl = req.url;
        }
    }
    var filePath = path.resolve('./public'+fileurl);
    var fileExt = path.extname(filePath);
    if(fileExt == '.html'){
          fs.exists(filePath, function(exists){
        if(!exists){
          res.writeHead(404, {'Content-Type': 'text/html'});
          res.end('<h1>Error 404' + filePath + 'not found </h1>');
          //the end() method sends content of the response to the client
          //and signals to the server that the response has been sent
          //completely
          return;
        }
        res.writeHead(200, {'Content-Type':'text/html'});
        fs.createReadStream(filePath).pipe(res);
      })
    }
}

fs.createReadStreamメソッドは、指定されたファイルパス(public/index.html)のファイルを読み取り、pipe()はクライアントのビューの応答(res)に書き込みます。

2
Harrison Kamau

サーバーとクライアントの接続ごとに2つのソケットがあります(2つのエンドポイント)。ソケットはIP Address:Port Numberをバインドします。クライアントにはランダムなポート番号が割り当てられ、サーバーには専用のポート番号が割り当てられます。これは、ソケットの仕組みの基本的な説明です。

パイピングは、読み取り可能なストリームを書き込み可能なストリームにリダイレクトするために予約されています。

socket.pipe(socket)は何をしますか?すべてのデータを読み取り可能なストリーム(サーバー)から書き込み可能なストリーム(クライアント)にリダイレクトします。 @hexacyanideが指摘したように、イベントリスナーを追加することでこれを調整できます。

1
KrisT