Использование pipe() в Node.js net
У меня возникают проблемы, обертывая мою голову вокруг функции pipe
, показанной в нескольких примерах Node.js для модуля net.
var net = require('net');
var server = net.createServer(function (socket) {
socket.write('Echo server\r\n');
socket.pipe(socket);
});
Может ли кто-нибудь объяснить вам, как это работает и почему это необходимо?
Ответы
Ответ 1
Функция 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()
читает из читаемого потока и записывает в записываемый поток, как и Unix-канал. Он делает все "разумные" вещи на этом пути с ошибками, завершением файлов, если одна сторона отстает и т.д. Ваш конкретный пример несколько запутан, потому что socket
читается и записывается.
Проще всего понять пример в этом вопросе SO, где вы читаете HTTP-запрос и пишите в ответ http.
Ответ 3
На сервер-клиентское соединение (2 конечных точки) имеется 2 сокета. Socket привязывает IP Address:Port Number
. Клиент получает назначенные номера случайных портов, а сервер имеет выделенный номер порта. Это основное объяснение того, как работает сокет.
Протокол зарезервирован для перенаправления читаемого потока в записываемый поток.
Что делает socket.pipe(socket)
?
Он перенаправляет все данные из читаемого потока (сервера) в записываемый поток (клиент). Мы можем настроить это, добавив слушателей событий, как отметил @hexacyanide.
Ответ 4
Рассмотрим следующий обработчик запросов
`
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
) для представления клиента.