Unlimited Plugins, WordPress themes, videos & courses! Unlimited asset downloads! From $16.50/m
Advertisement
  1. Code
  2. Web Development

Изучаем серверное программирование на JavaScript с Node.js

by
Difficulty:IntermediateLength:LongLanguages:

Russian (Pусский) translation by Anton Lisovsky (you can also view the original English article)

На данный момент множество разработчиков говорят о Node.js, создавая высоконагруженные приложения, работающие в реальном времени. С Node.js вы можете использовать JavaScript как на клиенте, так и на сервере. В данном туториале мы установим Node и создадим вашу первую "Hello World" программу - масштабируемый сервер для стриминга Twitter сообщений.

Что такое Node.js?


NodeJS

Чаще всего JavaScript выполняется исключительно на стороне клиента, веб-браузера, но с недавних пор разработчики заинтересовались использование его на сервере, во многом благодаря проекту CommonJS. Из других заметных серверных JavaScript сред стоить отметить Jaxer и Narwhal. Однако Node.js отличается от подобных решений, так как в своей основе он работает следуея концепции событий, нежели потоков. Веб-сервер Apache к примеру, который обрабатывает PHP и другие CGI скрипты, основан на потоках, он создает отдельный поток для каждого запроса. Конечно этот подход работает для большинства приложений, однако модель основанная на потоках не подходит для приложений с продолжительным подключение в реальном времени, на подобии приложений как Friendfeed и Google Wave.

"Каждое действие с вводом/выводом (I/O) - асинхронное..."

Node.js использует цикл событий вместо потоков и способен поддерживать миллионы одновременных соединений. Недостаток данной модели заключается в том, что большинство серверов тратят большую часть времени ожидая операций по вводу/выводу, такие операции как чтение файла с жёсткого диска, получения доступа к удалённому веб-серверу или ожидание конца загрузки файл, данные операции гораздо медленнее, чем операции по работе с памятью. Каждое действие с вводом/выводом - асинхронное, это означает, что сервер может продолжать обрабатывать входящие запросы, во время операций по вводу/выводу. JavaScript отлично подходит для программирования основанного на событиях, он обладает анонимными функциями и замыканиями, что позволяет с легкостью создавать каллбеки и JavaScript разработчики уже знакомы с подобным способом программирования. Данная событийная модель делает Node.js невероятно быстрым и позволяет без проблем масштабировать приложения в реальном времени.


Шаг 1 установка

Node.js работает на Unix подобных системах, к примеру Mac OS X, Linux b FreeBSD. К сожалению Windows не поддерживается на данный момент времени, так что если вы пользователь Windows, можно воспользоваться установленной на Virtualbox Ubuntu. Чтобы это сделать, ознакомтесь со следующим туториалом. Вы должны воспользоваться терминалом для установки и запуска Node.js.

  1. Скачайте последний релиз Node.js с nodejs.org (на момент написания данной статьи, последняя версия - 0.1.31) и распакуйте zip архив.
  2. Откройте терминал и запустите следующие команды.

    Много сообщений будет показано в терминале во время установки и компиляции Node.js.


Шаг 2 Hello World!

Любое знакомство с новой технологией начинается с туториала "Hello World!", мы создадим простой HTTP сервер, который будет отправлять данное сообщение. Однако для начала, вы должны понять систему модулей Node.js. В Node функционал инкапсулирован в модули и для того, чтобы он работал нам предварительно следует загрузить интересующий нас модуль. Существует множество модулей, со списком можно ознакомиться в Node.js документации. Загрузить модуль можно с помощью функции require:

Данный пример загружает модуль sys, который содержит функции для выполнения системных задач, допустим вывод сообщения в терминал. Чтобы воспользоваться функцией модуля, вызовите её с помощью переменной в которую был сохранён данный модуль, в нашем случае sys.

Запуск этих двух строчек кода также прост, как запуск команды node с именем javascript файла в качестве аргумента.

Этот пример выведет "Hello World!" в терминал, после того, как будет запущен.

Для создания HTTP сервера, нам нужно будет вызвать require для http модуля.

Этот скрипт импортирует sys и http модули и создаёт HTTP сервер. Анонимная функция передаваемая в http.createServer будет вызвана, каждый раз когда совершается запрос к серверу. Как только сервер будет создан, он будет прослушивать порт 8080. Когда приходит запрос к серверу, сначала отправляем хедер с типом контента (content type) и  статус кодом 200 - успешно (successful). Затем мы посылаем "Hello World!" и закрываем соединение. После чего вы можете заметить, как мы явно закрываем соединение. Таким образом мы можем просто передавать данные клиенту, не закрывая соединения. Если запустить данный скрипт и перейти по адресу в браузере - http://localhost:8080/, вы увидите "Hello World!"


Шаг 3 простой статичный файловый сервер

Хорошо, мы создали HTTP сервер, но кроме "Hello World" ничего не посылается, не важно какой адрес мы введём. Любой HTTP должен быть способен посылать статичные файлы, такие как HTML, изображение и другие файлы. Код ниже делает следующее:

Мы начали, загрузив все необходимые нашему коду модули. Включая sys, http, url, path, также fs или модули для работы с файловой системой. Далее мы создаём HTTP сервер, как делали это раньше. На этот раз, мы используем модуль url для парсинга входящих URL запросов, который будет находить путь к запрашиваемому файлу. Мы нашли имя файла на жёстком диске сервере используя path.join, который объединяет process.cwd(), или текущую рабочую директорию, к пути запрашиваемого файла. Далее, мы проверяем существует-ли файл, это асинхронная операция, тем самым требует каллбека. Если файл не существует, сообщение 404 Not Found будет послано пользователю и произойдёт возврат функции. В противном случае, мы читаем файл используя модуль fs, используя бинарную кодировку и посылая файл пользователю. Если случится ошибка чтения файла, мы показываем сообщение ошибки пользователю и закрываем соединение. Так как всё это работает асинхронно, сервер будет в состоянии обрабатывать другие запросы, читая файл с диска, не важно насколько он большой.

Запустив данный пример и открыв http://localhost:8080/path/to/file, файл будет показан в браузере.


Шаг 4 стриминг твитов в реальном времени

Используя уже работающий, статичный файловый сервер, мы создадим сервер на Node.js, который будет показывать твиты клиенту, которые будут обрабатываться статичным файловым сервером. Для начала нам понадобиться один дополнительный модуль для данного примера: модуль для работы с событиями - events. В Node существует концепция называемая EventEmitter, который используется для обработки слушателей событий (event listeners) для асинхронных задач. Также как jQuery или другие JavaScript фреймворки для клиентской части, когда вы привязываете (bind) слушатель события к таким вещям, как клики мышки и AJAX запросы, Node позволяет вам привязать слушатель событий ко многим вещам, некоторые мы уже использовали. Сюда можно включить все операции ввода/вывода, такие как чтение или запись файла, проверка существует-ли файл, ожидание HTTP запросов и так далее. EventEmitter абстрагирует логику связывания (binding), развязывания (unbinding) и вызвает слушатели событий. Мы используем EventEmitter посылая сигналы слушателю события, когда новые твиты будут загружены. Первые несколько строк нашего стримера твитов включают все необходимые модули и определяют функцию для обработки статичных файлов, которые были взяты из предыдущего примера.

Ранее мы использовали http модуль для создания сервера, но кроме этого у нас есть возможность, с помощью модуля, создать HTTP клиент. Мы будем использовать HTTP клиент для загрузки твитов из публичного лога Twitter, для этого нам понадобится функция get_tweets.

Сперва мы создадим HTTP клиент на порту 80 для api.twitter.com, и создадим новый EventEmitter. Функция get_tweets создаёт HTTP "GET" запрос к публичному логу Twitter, и добавляется слушатель, который будет срабатывать когда сервер Twitter даст ответ. Так как Node.js асинхронный, данные из тела ответа приходят кусками, которые затем обрабатываются ответом "data" слушателя. Данный слушатель добавляет куски сообщения переменной body. Как только придут все кусочки сообщения, запустится слушатель "end", и мы распарсим входящие JSON данные. Если возвращается лишь одит твит, мы создадим событие "tweets" для нашего tweet_emitter, и передадим массив с новыми твитами. Это вызовет все слушатели событий для работы с событием "tweets", и посылает новые твиты каждому клиенту. Мы запрашиваем новые твиты каждые пять секунд, используя setInterval.

Наконец мы должны создать HTTP сервер для обработки запросов.

Также как мы сделали со статичным файловым сервером, мы создадим HTTP сервер работающий на порту 8080. Мы обрабатываем входящий URL, и если URL - "/stream", мы обработаем его, в другом случае мы передадим запрос отключения нашему статичному серверу. Стриминг представляет из себя слушатель, который будет отслеживать новые твиты от нашего tweet_emitter, которые будут отправляться функцией get_tweets. Мы также создали таймер, для остановки запросов, которые длятся больше 10 секунд, отправляя им пустой массив. Когда появляются новые твиты, мы отправляем эти твиты в качестве JSON данных и останавливаем таймер. Вы лучше поймёте как это работает изучив код на стороне клиента, который показан ниже. Сохраните его как test.html в туже директорию где находится серверный JavaScript.

У нас имеется простая HTML страница, в которую добавляется библиотека jQuery и создан неупорядоченный список, куда мы будем вставлять твиты. Клиентский JavaScript кеширует список твитов и запускает функцию load_tweets, по прошествию одной секунды. Так браузеру даётся достаточно времени для завершения загрузки страницы, до того как мы совершим AJAX запрос к серверу. Функция load_tweets очень проста; она использует jQuery функция getJSON для загрузки /stream. Когда приходит ответ, мы обходим циклом все твиты и добавляем их к списку твитов. После этого снова вызывается функция load_tweets. Тем самым создаётся цикл, который эффективно загружает новые твиты, таймер останавливается через десять секунд по истечению таймаута на сервере. Каждый раз когда у нас есть новые твиты, они посылаются клиенту, который поддерживает непрерывное соединение с сервером. Данный метод называется long-pooling.

Если запустить сервер с помощью node и открыть http://localhost:8080/test.html, вы увидете публичный лог твиттера в вашем браузере.


Следующие шаги

Node.js очень впечатляющая технология, с которой легко создать высоконагруженные приложение в реальном времени. Надеюсь вам удалось понять все преимущества и можете их использовать в собственных приложениях. Поскольку Node обладает отличной системой модулей, можно с легкостью использовать написанный ранее код для ваших приложений, также имеется большое количество сторонних модулей, созданных для чего угодно - включая соединение с базой данных, шаблонизаторы, почтовые клиенты и даже целые фреймворки соединяющие всё вместе взятое. Вы можете ознакомиться с полным списком модулей на вики Node.js, ещё больше туториалов могут быть найдены на How To Node. Я также рекомендую посмотреть видео с JSConf, в котором Ryan Dahl, создатель Node, объясняет философию стоящию позади создания и дизайна Node. Оно доступно.

Надеюсь вам понравился данный туториал. Если у вас есть какие-либо комментарии, можно их оставить здесь, либо отправить сообщение на Twitter. Всего доброго!

Advertisement
Advertisement
Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.