По определению, NodeJS - это управляемая событиями неблокирующая среда выполнения для JavaScript, которая стала очень популярной на стороне сервера. Это потому, что Nodejs имеет управляемую событиями архитектуру, способную выполнять асинхронный ввод-вывод. В этом посте исследуется, на что похожа эта управляемая событиями архитектура, и как использовать управляемую событиями природу Nodejs очень простым и базовым способом.

Для кого этот пост?

Если вы уже программировали на Nodejs, этот пост для вас, потому что с доступными библиотеками и фреймворками в сообществе npmjs у большинства разработчиков никогда не возникает необходимости испытать основные движущие возможности Nodejs. Если вы новичок в Nodejs, это руководство для начинающих вам подойдет. Как новичок, вы также можете пройти это руководство, хотя, возможно, вам будет сложно начать с правильного пути. В любом случае, вы узнаете, насколько хорош Nodejs, если подходить к нему с этой стороны.

Пример из практики.

Прежде чем мы начнем программирование, управляемое событиями, давайте найдем проблему, которая требует от нас использования событий. У меня просто отличная идея! Представьте, что у вас есть два интерфейса. HTTP-клиент, например веб-браузер и TCP-интерфейс, например, очень монолитный постилион, который принимает только потоковые TCP-сообщения.

По протоколу очевидны две вещи, которые делают вышеуказанную настройку невозможной:

  1. HTTP-клиент знает только, как отправить HTTP-запрос и получить HTTP-ответ, в то время как интерфейс TCP знает только, как получить сообщение, записанное в сокет, и ответить на него другим сообщением в потоковом режиме.
  2. HTTP-клиент может взаимодействовать только с веб-сервером HTTP, в то время как интерфейс TCP может связываться с клиентом TCP только через сокет.

Использование событий для решения проблемы.

Чтобы решить эту проблему, мы должны ввести две сущности. Веб-сервер и TCP-клиент выступают в качестве посредников.

Таким образом, с новым дизайном у нас есть HTTP-клиент, отправляющий запросы на веб-сервер, который использует TCP-клиент для записи сообщения в сокет, соединяющийся с TCP-сервером, который при получении потокового сообщения записывает обратно в сокет. Вы заметите, что на уровне сокетов TCP все основано на событиях. Теперь обработчик запросов веб-сервера должен использовать события для ожидания сообщения на клиенте, который также должен использовать событие для уведомления веб-сервера, когда сервер TCP записывает ответное сообщение.

Предварительные требования.

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

  1. ES6: в этом посте используются некоторые из последних функций JS, описанных в основных характеристиках ES6.
  2. Nodejs Net: Поскольку наша задача использует необработанный TCP, нам нужен сетевой модуль Nodejs. Этот модуль также полностью основан на событиях, что делает его использование хорошим обучением для программирования, управляемого событиями.
  3. Expressjs: мы используем Express в качестве веб-сервера, хотя мы можем создать его для себя, например, этот здесь.
  4. События Nodejs: этот модуль будет взаимодействовать с TCP и HTTP.

Краткая общая картина событий Nodejs

Узел является однопоточным и обеспечивает неблокирующую архитектуру с помощью цикла событий. Таким образом, каждая функция выполняется при возникновении события. Это основная идея, которую мы хотим здесь увидеть.

Хорошо, теперь, когда у нас есть все необходимое, давайте приступим.

TCP-клиент и TCP-сервер

Давайте создадим TCP-клиент и сервер, которые мы будем подключать к HTTP-клиенту.

Что касается TCP-сервера, то он у нас и будет. Этот сервер прослушивает порт, к которому мы можем подключиться, и получать информацию о кодах состояния HTTP. Вы заметите, что весь код здесь основан на событиях, например, когда создается новое соединение, генерируется событие connection и вызывается слушатель с сокетом, связанным с соединением, в качестве аргумента. То же самое относится и к подписчикам, например к данным, ошибкам и т. Д., Которые созданы для прослушивания сокета.

Теперь у нас есть TCP-сервер, давайте его протестируем. Сначала запустите сервер. Если вы работаете в Windows, просто запустите putty и выберите telnet, затем введите 127.0.0.1 в имя хоста и 9670 в качестве порта. как показано ниже. Нажмите Открыть, у вас должен появиться новый терминал, похожий на окно. Ввод 404 или 500 должен установить разговор через созданный сокет.

Если вы используете Unix, по умолчанию должен быть установлен telnet. Если не гуглить, в каком пакете есть telnet для вашей ОС. Вы должны в конечном итоге выпустить

telnet 127.0.0.1 9670

Это должно открыть соединение, доступное для записи, как это.

Как насчет TCP-клиента в Nodejs. Нам нужен TCP-клиент, который будет использоваться веб-сервером для связи с TCP-сервером. Клиент будет выглядеть так.

Вы должны заметить, что у нас нет прослушивателя событий on data в этом клиенте. Это сделано специально, потому что прослушиватель данных будет создан в файле веб-сервера. Вот почему мы экспортировали клиента. Когда вы запускаете клиент самостоятельно, он должен нормально подключаться к серверу.

Создание веб-сервера.

Установите экспресс и создайте сервер с одной конечной точкой. Мы вызываем сервер с кодом состояния запроса, который является кодом, который мы хотим получить от TCP-сервера. Веб-сервер возьмет код из запроса и запишет его в сокет. Затем дождитесь ответного сообщения. Мы будем использовать модуль событий Nodejs, чтобы заставить эту работу работать. Вот полный код веб-сервера.

Теперь, как вы можете видеть, мы используем модуль событий Nodejs для создания прослушивателя событий после записи в сокет. Слушатель событий ожидает события, имя которого является кодом, отправленным в запросе состояния. Когда TCP-клиент получает ответ через свой приемник событий данных, мы генерируем событие, имя которого является кодом состояния, который мы получили из HTTP-запроса. Вот фрагмент образца запроса к этому серверу, который будет работать, когда сервер TCP работает.

curl localhost:8090?statusCode=500

Теперь у нас есть готовое рабочее приложение, основанное на событиях. Однако программирование на основе событий связано с множеством обязанностей.

Ключевые моменты, о которых следует помнить.

  1. Утечки памяти: обычно в JavaScript почти нет управления памятью. Но когда вы начинаете использовать основные модули Nodejs, такие как сеть, события и потоки, некоторый уровень управления памятью очень удобен.
  2. Простота: с такими слушателями и эмиттерами очень легко потеряться в собственном коде, каким бы простым он ни был. Здесь больше всего помогают простые, модульные и абстрактные.
  3. Не используйте анонимные функции со слушателями. По моему опыту, вы всегда захотите завершить прослушиватели / обработчики событий в памяти, но это становится трудным, когда прослушиватель является анонимной функцией. Вместо этого используйте именованные функции.
  4. Перед развертыванием отладьте использование памяти приложением. Это поможет вам с множеством неприятностей в будущем.

Помимо этой статьи.

Возможно, вам понравился этот пост, и вы спрашиваете, что делать дальше, зная, как выполнять код, полностью основанный на событиях. Что ж, вот несколько вещей, над которыми я все еще смотрю.

  1. Запуск приложений на основе событий в кластере, при котором обмен данными осуществляется через IPC или базу данных в памяти, такую ​​как Redis. Это идеально подходит для микросервисов.
  2. Написание приложений с эффективным использованием памяти на низкоуровневом C ++ и выполнение на Nodejs. Это превращает управление памятью в прогулку по парку.
  3. Использование машинописного текста для кода, который требует проверки типов, особенно с буферами и потоками сокетов. Это поможет вам с приложениями Интернета вещей, развернутыми с помощью Node.

Заключение.

Надеюсь, этот пост вдохновил вас на изучение Nodejs. Спасибо. Ваше здоровье.

Весь код, использованный в этом посте, находится на GitHub.