10. Уроки Node.js. Node.JS как веб-сервер

maxresdefault

Всем привет! На этом занятии мы познакомимся с Node.js уже в роли веб-сервера. Создадим для этого новое приложение. Настройте пожалуйста свой редактор таким образом чтобы он знал что  вы делаете именно Node.js-проект и поддерживал соответствующие автодополнения и глобальные переменные. Далее создадим server.js и в нем первым делом подключаю модуль:

Об этом модуле мы еще поговорим подробнее, но на текущий момент нам необходим из него один объект:

Как следует из его названия, он умеет слушать ip-порт и отвечать на входящие запросы. Для того, чтобы дать ему ip-порт, используется команда:

А для того, чтобы отвечать на запросы, используются события. Сервер является  EventEmitter, и при входящих запросах инициируется соответствующее событие, которое называется request. Его обработчик получает два объекта:

Первый requestэто входящий запрос, он содержит информацию, которая присылает браузер, включая, в частности, url пришедшего запроса. И второй параметр – это объект ответа. Из первого мы читаем, во второй пишем. Конкретно эта функция тут же заканчивает выполнение запроса, отсылая фразу «Hello, world!». Давайте посмотрим, как это работает. Для этого я создам конфигурацию у себя в WebSorm 2016 для запуска Node.js приложения. Выбираем Node.js, там уже указан путь к Node. Добавляем  путь к исполнимому файлу. Пожалуйста повторите эту процедуру но уже в своем редакторе. Запустим наш server. Работает.

Теперь зайдем на url браузера – http://127.0.0.1:1337/ . Замечательно! По виду все работает. Чтоб в этом убедиться, создадим  переменную

которая будет вводить текущий считчик запросов.  Захожу в браузер и попытаюсь обновить страницу. Но мои попытки не приносят результата. Почему? Node.js устроен так, что запустившись и считав файл модуля, в данном случае это главный файл, он же и единственный, Node создает из него объект module, и этим объектом в дальнейшее пользуется. Соответственно, при изменениях данного файла Node просто не подбирает эти изменения, потому что файл уже обработан, а объект module готов. Чтобы заставить Node перечитать файл, самый простой способ – запустить сервер еще раз. Но если я сейчас нажму play, то произойдет ошибка: EADDRINUSE – это означает, что адрес уже используется, потому что Node server.js попыталась запуститься еще раз, не прекратив действия уже запущенной программы. Предыдущий сервер уже занял этот ip-порт.  Что делать? Например, можно взять и подредактировать конфигурацию, добавив галочку в Single instance only (сервер может быть запущен в единственном экземпляре). Жмем повторный play, который нам предложить убить текущий запуск. Попрошу не предупреждать об этом в будущем, а просто убивать его. Теперь снова повторное нажатие кнопки play или Ctrl+R будут перезапускать текущий сервер, а вовсе не делать новый. Если вы работаете в console, то это вообще не проблема. Убиваете текущий Node.js, стартуете новый. В дальнейшем мы посмотрим, как это оптимизировать.

Теперь перехожу в браузер и нажимаю Ctrl+R. Как видим, счетчик запросов увеличивается не на 1, а на 2. Это потому что браузер устроен так, что вместе с собственной страничкой он делает еще один запрос. Он делается на url favicon.ico. В данном случае, мы никакой favicon.ico не отдаем, поэтому браузер каждый раз его повторяет. Получается, что одно обновление страницы приводит к двум запросам, по крайней мере, в текущем контексте, в Chrome.

Мы сделали наш первый сервер на Node.js. В дальнейшем будем работать, чтобы сделать его гораздо мощнее, интереснее. Перед тем, как мы продолжим, небольшая ремарка: если вы смотрите сам сайт Node.js, то пример, аналогичный нашему. там выглядит немножко по-другому. Основное отличие в том, что здесь используется new server, а там http createServer.  Это одно и то же. Здесь обработчик запроса ставится явно, а там он передается аргументам. Передача аргументов – это тоже установка обработчика, просто такой дополнительный синтаксис. Он чуть-чуть короче, но я выбрал для примера этот синтаксис, потому что он более нагляден и показывает то, что реально происходит.

А теперь, если вы внимательно слушали, то у вас не вызовет проблемы ответить на следующий небольшой вопрос. Здесь есть обработчик события request, скажите, пожалуйста, как, не глядя в документацию, сказать, какие еще есть события для сервера и когда они вызываются, в каком порядке при обработке этого запроса? Почему я прошу не смотреть в документацию? Тут две причины. Во-первых, так интереснее, во-вторых, сервер (var server = new http.Server()  ), на самом деле, наследует net.Server, модуля net, а он  наследует EventEmitter:

// http.Servernet.Server→EventEmitter

 

Вот такая иерархия. Соответственно, некоторые события сервера описаны вот здесь, в http.Server а  некоторые описаны в документации к net.Server:

И просто, взглянув в книгу, понять точный порядок событий достаточно сложно. Сейчас я расскажу, как это сделать. Подсказка находиться вот в этой строке:

// http.Servernet.Server→ EventEmitter

Сервер является EventEmitter. Это означает, что все события генерируются вызовом server.emit. понятно, что мы сами не вызываем этот метод, в данном случае его вызывает сам Node.js, а мы просто ставим обработчики. Но ничто нам не мешает переопределить этот метод на наш собственный. Метод emit принимает название события и необходимые данные для него:

В данном случае это будут req, res. Но нас интересуют только названия событий, которые мы при помощи console.log будем выводить.  А далее мы буде передавать вызов исходному методу emit:

Посмотрим, что получилось. Перезапустим сервер. И тут же видим первое событие – listening. Это означает, что сервер начал слушать соединение:

Далее, захожу в браузер и перехожу по адресу. Обратите внимание, я нажимаю Ctrl+R, и request увеличивается, причем, даже по 2 штуки. А connection одно-другое, а новых нет, потому что это событие connection возникает тогда, когда браузер открывает серверу новое сетевое соединение, а request присылает запрос. Браузер устроен так, что одно сетевое соединение он старается использовать по максимуму. Называется это KeepAlive. Он его сохраняет и по нему гонит новые запросы.

Итак, мы создали простейший веб-сервер, познакомились с соответствующим объектом http.Server и событиями, которые в нем возникают.

Код нашего урока можно найти в нашем репозитории.

D-03-WebServeHosting

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

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

About the author

Stay Informed

It's important to keep up
with industry - subscribe!

Stay Informed

Looks good!
Please enter the correct name.
Please enter the correct email.
Looks good!

Related articles

Уроки Express.js . Логгер, Конфигурация, Шаблонизация с EJS. Часть 2.

Favicon – это все connect Middleware, он смотрит, если url имеет вид favicon.ico, то он читает favicon и ...

3. Уроки Express.js. Шаблонизация с EJS: Layout, Block, Partials

В реальной жизни у нас обычно больше, чем один шаблон. Более того, если уж так ...

24.11.2016

Уроки Express.js. Основы и Middleware. Часть 2.

Всем привет! Давайте продолжим наш урок об основах Express и Middleware. Итог (добавим в ...

No comments yet

Sign in

Forgot password?

Or use a social network account

 

By Signing In \ Signing Up, you agree to our privacy policy

Password recovery

You can also try to

Or use a social network account

 

By Signing In \ Signing Up, you agree to our privacy policy