在Node.js net中使用pipe()函数

79

我对在 Node.js 的 net 模块中出现的 pipe 函数感到困惑。

var net = require('net');

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

有人能解释一下这是怎么工作的,以及为什么它是必需的吗?

4个回答

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

2
你能否提供一下pipe(net.Soctket)的文档链接?或者是没有相关文档? - Paweł Brewczynski
9
它位于这里。然后,如果您在这里看一下,它指出 net.Socket 实例实现了一个双工流。 - hexacyanide
1
是的,它意味着它继承自 stream.Duplex,而 stream.Duplex 又同时继承了 stream.Readablestream.Writable。在这个上下文中,“接口”并不严格遵循面向对象编程中“接口”的定义,它只是应用程序之间的联系点。 - hexacyanide
1
"应用程序之间接触点"是什么意思?为什么使用这样一个可能会产生误导的术语?而且他们不会说它是如何实现的(该对象是否在原型链中,或者是一个混入)。 - Paweł Brewczynski
我的意思是,“接口”(interface)的另一个定义是两个系统交互的点——我确实没有更好的解释方式。至于流的实现,你可以查看源代码,比如像这里。你可以看到流原型直接从套接字的原型方法中调用。 - hexacyanide
显示剩余2条评论

6

pipe()方法从可读流中读取数据并将其写入可写流,类似于Unix管道。在此过程中,它会处理所有“合理”的情况,如错误、文件末尾、一侧滞后等。您的特定示例可能稍微令人困惑,因为socket既可读又可写。

一个更易理解的例子可以在这个 Stack Overflow 问题中找到,在该问题中,您从http请求中读取数据并将其写入http响应。


3
每个服务器-客户端连接(2个端点)有2个套接字。套接字绑定IP地址:端口号。客户端被分配随机端口号,而服务器有专用端口号。这是套接字工作原理的基本解释。
管道保留用于将可读流重定向到可写流。 socket.pipe(socket)是什么意思?它将从可读流(服务器)到可写流(客户端)的所有数据重定向。我们可以通过添加事件侦听器来进行微调,如@hexacyanide所指出的那样。

2
请考虑以下请求处理程序
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) 以供客户端查看。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接