Масштабируемость. Большое количество данных. Реальное время Вот некоторые из проблем, с которыми сталкивается веб-приложение в современной всемирной паутине. Это где Node.js и его неблокирующая модель ввода / вывода вступает в игру. Эта статья познакомит вас с одним из самых мощных API-интерфейсов Node для потоковой обработки данных.
Зачем использовать потоки?
Давайте рассмотрим следующий пример:
var http = require('http')
, fs = require('fs')
;
var server = http.createServer(function (req, res) {
fs.readFile(__dirname + '/data.txt', function (err, data) {
res.end(data);
});
});
server.listen(8000);
Этот код работает отлично. В этом нет ничего плохого, кроме того, что Node.js
буферизирует все содержимое data.txt перед отправкой данных обратно клиенту. С увеличением запросов клиентов ваше приложение может начать потреблять много памяти. Кроме того, клиенты должны будут ждать, пока приложение сервера прочитает весь файл, что приведет к увеличению задержки.
Давайте посмотрим на другой пример:
var http = require('http')
, fs = require('fs')
;
var server = http.createServer(function (req, res) {
var stream = fs.createReadStream(__dirname + '/data.txt');
stream.pipe(res);
});
server.listen(8000);
Здесь, чтобы преодолеть проблемы масштабируемости, мы используем API потоков. Использование объекта потока гарантирует, что data.txt отправляется клиентам по одному куску за раз, когда они считываются с диска, без буферизации сервера и времени ожидания на клиенте.
Что такое потоки?
Потоки могут быть определены как непрерывный поток данных, которыми можно асинхронно манипулировать при поступлении (или выходе) данных. В Node.js потоки могут быть доступны для чтения или записи. Читаемый поток — это объект EventEmitter
который генерирует события data
В нашем предыдущем примере читаемый поток использовался для передачи содержимого файла клиенту HTTP. Когда поток достигает конца нашего файла, он генерирует end
data
Кроме того, читаемый поток может быть приостановлен и возобновлен.
Потоки с возможностью записи , с другой стороны, принимают потоки данных. Этот тип потока также наследуется от объекта EventEmitter
write()
end()
Первый метод записывает данные в буфер и возвращает значение true
false
end()
Ваше первое приложение Streams
Давайте внимательнее посмотрим на потоки. Для этого мы собираемся создать простое приложение для загрузки файлов. Прежде всего, нам нужно создать клиент, который читает файл с использованием читаемого потока и передает данные в конкретное место назначения. На другом конце канала мы реализуем сервер, который сохраняет загруженные данные с использованием потока с возможностью записи.
Начнем с клиента. Начнем с импорта модулей HTTP и файловой системы.
var http = require('http')
, fs = require('fs');
Затем мы определяем наш HTTP-запрос.
var options = {
host: 'localhost'
, port: 8000
, path: '/'
, method: 'POST'
};
var req = http.request(options, function(res) {
console.log(res.statusCode);
});
Теперь, когда у нас есть request
request
var readStream = fs.ReadStream(__dirname + "/in.txt");
readStream.pipe(req);
Как только поток завершит чтение всех данных, мы закрываем соединение с сервером, вызывая метод end()
request
readStream.on('close', function () {
req.end();
console.log("I finished.");
});
Сервер
Как и в случае с клиентом, мы начинаем с импорта модулей Node.js. Затем мы создаем новый поток для записи, который сохраняет данные в текстовый файл.
var http = require('http')
, fs = require('fs');
var writeStream = fs.createWriteStream(__dirname + "/out.txt");
Чтобы позволить нашему клиентскому приложению загружать файлы, нам нужно создать новый объект веб-сервера. Поскольку данные поступают из объекта request
var server = http.createServer(function (req, res) {
req.on('data', function (data) {
writeStream.write(data);
});
req.on('end', function() {
writeStream.end();
res.statusCode = 200;
res.end("OK");
});
});
server.listen(8000);
Обратите внимание, что объекты req
res
createServer()
Мы можем прослушать событие data
Вывод
В этой статье был представлен один из самых мощных инструментов Node.js, API потоков. В ближайшие недели мы углубимся в мир потоков, исследуя все различные типы, встроенные в Node.js, а также сторонние потоки.