03Oct

banner
Всем привет. Если вы привыкли глубоко вникать в происходящее, то эта статья для вас. Здесь мы разберем те вопросы, которые рано или поздно обязательно возникнут при разработке, и ответа на которые требует глубокого понимания, как именно работает Node.js. Например, здесь (serverAsync.js смотрите файлы нашего предыдущего урока) для чтения файла использован асинхронный вызов:

 fs.readFile('index.html', function(err, info) {
            if(err) {
                console.error(err);
                res.statusCode = 500;
                res.end("A server error occurred ");
                return
            }

            res.end("info");
        });

Но любые ли операции можно сделать асинхронными? Насколько действительно опасны асинхронные вызовы и что делать, если асинхронная операция есть, и избежать ее никак нельзя? Как снизить ее вредный эффект? Что происходит с теми запросами, которые приходят, пока интерпретатор занят? Например, если здесь (serverSync.js) есть синхронные файлы:

info = fs.readFileSync('index.html');

и пришло 10 клиентов. Получают ли они отказ в обслуживании? Или выстраивается очередь из них? Ответы на эти и многие другие вопросы Вы получите во время чтения этой статьи.

1

Для того, чтобы глубже понимать происходящее, познакомимся с библиотекой libUV. К этой библиотеке не надо обращаться каким-то явным образом. Она написана на языке С и встроена в сервер Node.js. Библиотека libUV отвечает за две принципиально важные вещи. Первое – это кроссплатформенные операции ввода-вывода, работа с файлами, работа с сетью. Мы через JavaScript даем команду Node.js просчитать какой-то файл или отправить данные по сети. А Node.js чтобы это сделать уже внутри себя использует библиотеку libUV. Таким образом, libUV отвечает за кроссплатформенную реализацию этих функций. Именно она уже знает, как работать с Windows, Linux и т.д.

Вторая область ответственности libUV это поддержка основного событийного цикла Node.js. Оказывается, когда мы запускаем какой-то скрипт, то он запускается в режиме цикла. Этот цикл чередует выполнение JavaScript, который обеспечивается виртуальной машиной V8 с ожиданием различных событий: ввода-вывода, срабатыванием таймеров, за которые также отвечает библиотека libUV. Этот цикл будет продолжаться до тех пор, пока возможно появление каких-то новых событий, ввода-вывода или таймера, которые нужно будет обработать.

Для примера разберем, что происходит при запуске вот такого сервера:

var http = require('http');
var fs = require('fs');

var server = new http.Server();

    server.on('request', function(req, info) {

    if (req.url == '/') {

        fs.readFile('index.html', function(err, info) {
            if(err) {
                console.error(err);
                res.statusCode = 500;
                res.end("A server error occurred ");
                return
            }

            res.end("info");
        });

    } else { /*404 */ }
});

server.listen(3000);

Вначале срабатывает  JavaScript. Он подключает модули:

var http = require('http');  
var fs = require('fs');  

Создает объект:

var server = new http.Server();  

Вешает обработчик:

server.on('request', function(err, info) {

То, что внутри этой функции, пока неважно, обработчик пока еще не сработал. Последняя строчка – это вызов команды listen.

server.listen(3000);

Это команда работы с сетевыми соединениями.

2

Она, попадая в Node.js, проходит через его С++ код, превращается в вызов внутреннего метода TCPWrap::listen. Этот внутренний метод уже вызывает библиотеку libUV, а именно, ее метод uv__listen, который как раз осуществляет всю работу. Он, в зависимости от операционной системы, вешает обработчик соединений на данный порт. К примеру для unix-системы используется системный вызов listen. Таким образом, libUV назначила обработчик, на соединение, на этот порт.

Этот обработчик, или в терминах libUV он называется watcher, является внутренним, то есть, мы к нему доступа не имеем. Это именно libUV его поставила, и когда что-то произойдет, например, когда придет новое соединение, то watcher сработает, вызовет соответствующие методы libUV, Node.js и, скорее всего, в конечном счете, даст нам какое-нибудь событие, например, connection. Но это все будет потом. А пока что listen просто повесила обработчик. Результат этого действия поднимается вверх по цепочке. Если все хорошо, то это приводит к событию listening в JavaScript. Если обработчик повесить не удалось, то error.

part2_blogimage1

Материалы взяты из данного скринкаста

We are looking forward to meeting you on our website soshace.com

21. Уроки Node.js. Writable Поток Ответа res, Метод pipe. Pt.1

Нашим следующим шагом будет использование потоков для работы с сетевыми соединениями. И начнем мы с отдачи посетителю файлов. Если помните, у нас была такая задача: если посетитель запросит следующий url, то отдать ему файл. Создадим файл pipe.js со следующим кодом:

6. Уроки Node.js. Util и Наследование

Всем привет! Тема ближайших статей: Самые часто используемые модули Node.js.

Первым методом, который мы изучим, будет метод util inspect модуля, встроенного util. Этот метод позволят красиво вывести любой объект, даже если у этого объекта, как в этом примере, есть ссылка на самого себя.

Leave a Reply