loader image
Прослушивание Websocket

Технология соединения WebSocket на сервере: преимущества и настройка

Стоит ли использовать WebSocket и как реализовать простой клиент и сервер на JavaScript?

WebSocket позволяет пользователю отправлять и получать сообщения на сервере. По сути, это способ связи между клиентом и сервером. Как происходит это общение?

Клиент и сервер

Веб-браузеры (клиенты) и серверы обмениваются данными через TCP/IP. Протокол передачи гипертекста (HTTP) – это стандартный прикладной протокол, созданный поверх TCP/IP. HTTP поддерживает запросы (от веб-браузера) и их ответы (от сервера).

Как это работает?

Давайте пройдёмся по этим шагам:

  1. Клиент (браузер) отправляет запрос на сервер.
  2. Соединение установлено.
  3. Сервер отправляет ответ.
  4. Клиент получает ответ.
  5. Соединение завершено.

Так выглядит общение между клиентом и сервером. Давайте посмотрим на шаг номер 5.

Соединение завершено

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

Что делать, если сервер хочет отправить сообщение клиенту?

Соединение должно быть успешно установлено, чтобы начать обмен данными. Решение состоит в том, что клиенту придётся отправить ещё один запрос, чтобы подключиться и получить сообщение.

Как клиент узнаёт, что сервер хочет отправить сообщение?

Давайте посмотрим на пример:

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

  • 0 секунд: Еда готова? (Клиент);
  • 0 секунд: Нет, подождите. (Сервер);
  • 1 секунда: Еда готова? (Клиент);
  • 1 сек: Нет, пожалуйста, подождите. (Сервер);
  • 2 сек: Еда готова? (Клиент);
  • 2 секунды: Нет, пожалуйста, подождите. (Сервер);
  • 3 сек: Еда готова? (Клиент);
  • 3 сек: Да, вот Ваш заказ. (Сервер).

Это называется HTTP-опросом (HTTP Polling). Клиент отправляет повторные запросы на сервер и проверяет, есть ли какое-либо сообщение для получения. Это не очень эффективно. Мы потребляем неоправданно много ресурсов. Ещё одна проблема – количество неудачных запросов.

Есть ли способ решить эту проблему?

Да, существует вариант метода опроса, который используется для преодоления неэффективности, и он называется Long-Polling.

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

Давайте посмотрим на этот длинный пример опроса:

  • 0 сек: Еда готова? (Клиент);
  • 3 сек: Да, вот Ваш заказ. (Сервер).

Задача решена! Но не полностью. Несмотря на то, что Long Polling работает, он очень затратен с точки зрения использования ЦП, памяти и полосы пропускания (мы блокируем ресурсы, оставляя соединение активным).

Что мы делаем в такой ситуации? Кажется, что всё выходит из-под контроля. Вернёмся к нашему спасителю: Веб-сокету.

Почему веб-сокеты (WebSocket)?

Как видите, Polling и Long Polling – довольно дорогие варианты для связи в реальном времени между клиентом и сервером.

Эти ограничения производительности являются причиной того, что вместо этого следует использовать WebSocket. Вебсокет не требует отправки запроса для ответа. Они допускают двусторонний поток данных, поэтому всё, что Вам нужно сделать, это «прослушать» данные. Вы можете просто «прослушать» сервер, и он отправит Вам сообщение, когда станет доступным.

Давайте посмотрим на производительность WebSocket.

Потребление ресурсов

На приведённой ниже диаграмме показана пропускная способность, необходимая для WebSockets и Long-Polling в трёх относительно распространённых сценариях:

Технология соединения WebSocket на сервере: преимущества и настройка

Разница огромна (для относительно большего количества запросов).

Скорость WebSocket

Вот результаты для 1, 10 и 50 запросов, обслуженных на соединение за одну секунду:

Технология соединения WebSocket на сервере: преимущества и настройка

Как видите, при использовании Socket.io выполнение одного запроса на соединение на 50 % медленнее, поскольку сначала необходимо установить соединение. Эти накладные расходы меньше, но всё же заметны для десяти запросов.

При 50 запросах с одного и того же соединения Socket.io уже на 50% быстрее. Чтобы лучше понять пиковую пропускную способность, давайте посмотрим на тест с большим количеством (500, 1000 и 2000) запросов на соединение:

Технология соединения WebSocket на сервере: преимущества и настройка

Здесь Вы можете видеть, что пик HTTP-теста составляет около ~950 запросов в секунду, в то время как Socket.io обрабатывает около ~3900 запросов в секунду. Эффективно, правда?

Примечание. Socket.io – это библиотека JavaScript для веб-приложений реального времени. Реализует Вебсокет внутри. Вы можете думать об этом как о оболочке поверх WebSocket, которая предоставляет множество других функций.

Как работает WebSocket?

Вот как Вы установите соединение WebSocket:

  1. Клиент (браузер) отправляет HTTP-запрос на сервер.
  2. Соединение устанавливается по протоколу HTTP.
  3. Если сервер поддерживает Вебсокет, он соглашается обновить соединение. Это так называемое «рукопожатие».
  4. После принятия исходное HTTP-соединение заменяется соединением WebSocket, использующим тот же протокол TCP/IP.
  5. В этот момент данные могут свободно передаваться между клиентом и сервером.

Давайте закодируем это

Мы создадим два файла:

  • Server;
  • Client.

Сначала создайте простой документ <html> с именем client.html, содержащий тег <script>. Давайте посмотрим, как это выглядит:

Клиент.html

Технология соединения WebSocket на сервере: преимущества и настройка

Теперь создайте ещё один файл server.js. Импортируйте модуль HTTP и создайте сервер. Пусть он прослушивает порт 8000. Он будет действовать как обычный сервер HTTP, прослушивая порт 8000.

Сервер.js

Сервер js

Запустите команду node server.js, чтобы начать прослушивание порта 8000.

Примечание. Вы можете выбрать любой порт. Мы выбираем 8000 без особых причин.

Наша базовая настройка клиента и сервера завершена. Просто, верно? Теперь перейдём к более приятным вещам.

Настройки клиента

Чтобы создать WebSocket, используйте конструктор WebSocket(), возвращающий объект WebSocket. Этот объект предоставляет API для создания и управления подключением WebSocket к серверной части.

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

Технология соединения WebSocket на сервере: преимущества и настройка

Конструктор WebSocket ожидает URL-адрес для подключения. В нашем случае это ws://localhost:8000 потому, что там работает наш сервер.

Сейчас это может немного отличаться от того, к чему Вы привыкли. Мы используем не протокол HTTP, а протокол WebSocket. Это сообщит клиенту, что мы используем протокол WebSocket, следовательно, ws:// вместо http://.

Теперь давайте создадим сервер WebSocket в server.js.

Сервер

Нам понадобится внешний модуль ws на нашем сервере узлов, чтобы превратить его в файл WebSocket.

Сначала мы импортируем модуль ws. Далее мы создадим сервера WebSocket и передадим его HTTP, прослушивающему порт 8000.

HTTP-сервер прослушивает порт 8000, а сервер WebSocket прослушивает его. Он в основном «слушает слушателя».

Теперь наш WebSocket следит за трафиком на порту 8000. Это означает, что он попытается установить соединение, как только клиент станет доступен. Наш файл server.js будет выглядеть так:

Технология соединения WebSocket на сервере: преимущества и настройка

Как мы говорили ранее, конструктор WebSocket() возвращает объект WebSocket, который предоставляет API для создания и управления подключением WebSocket к серверу.

В этом случае объект wss поможет нам прослушивать события, генерируемые, когда что-то происходит. Например, когда соединение установлено или разорвано и т.д.

Давайте посмотрим, как прослушивать сообщения:

Технология соединения WebSocket на сервере: преимущества и настройка

Метод on ожидает два аргумента:

  • имя события;
  • обратный вызов.

Имена событий, чтобы распознать, какое событие прослушивать/генерировать, и обратный вызов, чтобы указать, что с ним делать. Здесь мы регистрируем только событие headers.

Технология соединения WebSocket на сервере: преимущества и настройка

Это наш заголовок HTTP. Это именно то, что происходит за кулисами. Давайте разобьём его на основные факторы, чтобы лучше понять его.

Первое, что Вы заметите, это то, что мы получили код состояния 101. Возможно, Вы уже видели коды 200, 201, 404. 101 – это статус HTTP, информирующий об изменении протокола (101 Switching Protocols). Пишет «Эй, мне нужно обновление».

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

Браузер использует соединение HTTP, чтобы установить соединение с использованием протокола HTTP/1.1, а затем uaktualnia goс протоколом WebSocket.

Теперь всё имеет смысл

Событие «заголовки» генерируется до того, как заголовки ответа будут записаны в сокет. Это позволяет Вам проверять/изменять заголовки перед их отправкой.

Это означает, что Вы можете принять заголовок, отклонить или что-то ещё, что Вам нужно. Принятие запроса будет по умолчанию.

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

Технология соединения WebSocket на сервере: преимущества и настройка

Мы также прослушиваем событие message, которое исходит от клиента. Давайте реализуем это:

Технология соединения WebSocket на сервере: преимущества и настройка

Вот как это выглядит в браузере:

Технология соединения WebSocket на сервере: преимущества и настройка

В первом журнале содержится WebSocket список всех свойств объекта WebSocket, а во втором – MessageEvent свойство data. Если Вы внимательно посмотрите, то увидите, что мы получили наше сообщение от сервера.

Журнал будет выглядеть так:

Журнал сервера Websocket

Мы получили сообщение от клиента. Это означает, что наше соединение успешно установлено!

Предыдущая запись
Прорывной квантовый суперкомпьютер от Google в 241 миллион раз быстрее, чем машина 2019 года
Следующая запись
Val – новый язык программирования как альтернатива C++ и Rust?
Добавить комментарий
Ваш электронный адрес не будет опубликован. Обязательные поля помечены *