
Это пост №72 из серии, посвященный изучению JavaScript и его строительных компонентов. В процессе определения и описания основных элементов мы также поделимся некоторыми практическими правилами, которые мы используем при создании SessionStack, инструмента JavaScript для разработчиков, позволяющего идентифицировать, визуализировать и воспроизводить ошибки веб-приложений посредством воспроизведения сеанса с точностью до пикселя.
Введение
WebSocket API позволяет нам установить двустороннюю связь между клиентом — браузером и сервером. В результате данные могут передаваться от клиента к серверу и от сервера к клиенту. Кроме того, поскольку веб-сокеты всегда открыты, они обеспечивают поток данных в реальном времени в нашем приложении.
Первым шагом WebSocket является отправка клиентом HTTP-запроса на сервер с просьбой открыть соединение. И если сервер соглашается, он отправит ответ 101 Switching Protocols, после чего рукопожатие будет завершено. Таким образом, соединение TCP/IP остается открытым, что обеспечивает двунаправленный поток данных между сервером и клиентом с очень низкой задержкой.
WebSockets API позволяет нескольким клиентам одновременно подключаться к серверу. И это соединение остается открытым до тех пор, пока одна из сторон не отключится.
Типичным приложением WebSockets API является приложение для чата, и на изображении ниже показано, как это может работать:
На изображении выше каждый клиент-пользовательский браузер подключен через веб-сокет к серверу приложений чата. Поэтому, когда пользователь вводит сообщение и нажимает «Отправить», сообщение отправляется на сервер через соединение WebSocket. А сервер, в свою очередь, отправляет сообщение по веб-сокетам всем клиентам. Следовательно, они получают уведомление и видят сообщение. Здесь следует отметить, что эти сообщения осуществляются в режиме реального времени. А это означает, что никаких дополнительных запросов пользователя или Ajax-запросов не делается в любое время.
API WebSockets позволяет нам создавать функции в реальном времени, устанавливая двустороннее соединение — через сокет между клиентом и сервером. Таким образом, у WebSockets есть много приложений в программировании, в том числе:
- Приложение чата
- Многопользовательские браузерные игры
- Потоковые приложения
- Программное обеспечение для совместного редактирования кода
- Живой текст для спортивных/новостных сайтов
- Приложения для работы в режиме реального времени с несколькими пользователями.
- Онлайн-приложения для рисования на холсте
В этом руководстве мы узнаем больше о WebSockets, создав приложение чата. И предпосылки для получения максимальной отдачи от этой статьи изложены в следующем разделе.
Предпосылки
Чтобы следовать статье, необходимо следующее:
- Базовые знания Node.js
- На вашем компьютере должна быть установлена последняя версия Nodejs.
- Базовые знания JavaScript
Начиная
Итак, чтобы использовать WebSockets API, нам нужен серверный код. И чтобы получить это, мы создадим приложение Nodejs.
Выполните следующие шаги, чтобы загрузить приложение Nodejs:
- Создайте папку приложения и из папки инициализируйте приложение Nodejs, выполнив следующий код на своем терминале:
npm init -y
- Установите необходимые пакеты, запустив:
npm install express socket.io
И установите dev-зависимости, запустив:
npm install -D nodemon
- Настройте сценарии NPM, обновив свойство
scriptsв файлеpackage.json, как показано ниже:
- Теперь настройте экспресс-сервер, создав папку
srcв корневом каталоге. А в папкеsrcсоздайте файлindex.jsсо следующим кодом:
В приведенном выше коде мы обслуживаем статический файл HTML — файл index.html, используя метод res.SendFile. Поэтому всякий раз, когда пользователь указывает браузеру http://localhost:5000/, файл index.html отображается в браузере. И мы создадим этот файл index.html в следующем разделе.
Кроме того, в приведенном выше коде мы настроили экспресс-сервер и реализовали socket.IO на сервере. И мы узнаем об этом больше в следующем разделе.
А пока запускаем dev-сервер, запустив npm run dev и получаем:
Итак, после загрузки нашего приложения в следующем разделе мы сосредоточимся на правильном создании приложения для чата.
Создание чат-приложения с помощью WebSockets — Socket.IO
Чтобы установить сокетное соединение между браузером и нашим приложением Nodejs, мы будем использовать библиотеку с именем Socket.IO.
Библиотека Socket.IO используется путем установки ее как на клиенте, так и на сервере. И он обеспечивает сокетное соединение между клиентом и сервером — таким образом, он обеспечивает двунаправленную связь на основе событий в реальном времени между сервером и клиентом.
Настройте Socket.IO на сервере
В нашей текущей настройке приложения мы реализовали Socket.IO на сервере, используя метод http.createrSever из экспресса.
Когда клиент устанавливает соединение с Socket.IO на сервере, запускается событие с именем connection. И в нашей текущей настройке Socket.IO прослушивает это событие, используя метод socket.on.
И когда срабатывает событие connection, мы вызываем обратный вызов и записываем made socket connection и сокет ID в консоль.
Эта функция обратного вызова принимает объект socket в качестве аргумента. И этот объект socket относится к экземпляру socket между клиентом и сервером. Таким образом, если к серверу подключаются десять разных клиентов, каждый клиент будет иметь свой socket экземпляр.
Настройте Socket.IO на клиенте
Чтобы настроить Socket.IO на клиенте, создайте папку pubic в корневом каталоге. И в папке public создайте файл index.html со следующим кодом:
И в браузере получаем:
Теперь нам нужно настроить Socket.IO. Добавьте эту строку кода в раздел header файла index.html, чтобы загрузить socket.io-client:
<script src=”/socket.io/socket.io.js”></script>
Строка кода выше предоставляет глобальную переменную io, конечную точку GET /socket.io/socket.io.js, а затем подключается.
Теперь, чтобы проверить, успешно ли загружен socket.io-client, добавьте над закрывающим тегом body следующий код:
И обновите браузер. Мы получаем:
На изображении выше мы видим, что made socket connection, за которым следует socket id, регистрируется в консоли, подтверждая, что соединение Websocket установлено между сервером и клиентом.
Кроме того, в дальнейшем наш клиентский код JavaScript будет писаться внутри этих тегов script над элементом body.
Отправка сообщений с помощью Socket.IO
В предыдущих подразделах мы настроили Socket.IO на клиенте и сервере. Но в этом разделе мы будем работать над отправкой сообщений через сокеты.
В нашем приложении чата, когда мы отправляем данные — сообщение чата из браузера через сокет на сервер, сервер получает это сообщение и отправляет данные — сообщение всем клиентам, которые к нему подключены.
Поэтому, чтобы обработать это, когда пользователь нажимает кнопку отправки, мы будем передавать событие от клиента на сервер через созданный сокет.
Чтобы реализовать это, нам нужно получить все необходимые элементы DOM, добавив следующий код после комментария // Query DOM в скрипты index.html:
Затем мы добавляем прослушиватель событий к кнопке отправки для прослушивания событий click, добавляя следующий код под комментарием // Emit events в сценарии index.html:
В приведенном выше коде мы добавили прослушиватель событий к кнопке отправки для прослушивания события click. И когда происходит событие click, socket.emit вызывается в обратном вызове обработчика событий.
Метод socket.emit принимает два аргумента: имя сообщения — в данном случае chat и объект, содержащий сообщение или данные, которые мы отправляем на сервер.
Итак, на сервере мы добавим прослушиватель событий для прослушивания этого отправленного события. Для этого измените метод io.on в файле index.js, как показано ниже:
В приведенном выше коде мы прослушиваем сокет для отправки сообщения chat, вызывая метод socket.on. А метод socket.on принимает два аргумента: сообщение chat и обработчик события — callback.
Теперь мы вызвали метод io.sockets.emit в функции обратного вызова, чтобы отправить это сообщение всем клиентам, подключенным к серверу через WebSocket. И это позволяет всем в чате видеть сообщение.
Обратите внимание, что io.sockets относится ко всем веб-сокетам, созданным разными клиентами, подключенными к серверу. И io.sockets.emit(‘chat’, data) выдает сообщение — данные от клиента, отправившего сообщение, всем подключенным клиентам — в коллекции io.sockets.
Теперь с нашей текущей настройкой пользователь может отправить сообщение с клиента на наш сервер. И сервер, получив сообщение, отправляет сообщение чата обратно во все сокеты в коллекции io.sockets. Таким образом, отправив сообщение всем подключенным клиентам.
После этого на стороне клиента нам нужен способ отобразить полученное сообщение в браузере. Поэтому добавьте следующий код под комментарием // Listen for events в разделе script файла index.html:
В приведенном выше коде socket.on прослушивает сообщение чата и вызывает обратный вызов — обработчик событий при получении сообщения чата. А в обработчик события мы добавили код, который отрисовывает сообщение на сервер.
Таким образом, у нас работает базовая функциональность чата. Мы можем передавать данные от клиента на сервер и обратно с сервера всем клиентам, подключенным через WebSocket.
Широковещательные сообщения
В этом разделе мы будем использовать широковещательную рассылку сообщений для уведомления других клиентов, когда пользователь набирает сообщение. И чтобы реализовать это, добавьте следующий код под комментарием // Broadcast feedback when user types:
В приведенном выше коде мы добавляем прослушиватель событий, который прослушивает событие keypress к элементу сообщения input. И когда это событие срабатывает, мы генерируем событие typing из обработчика событий, вызывая socket.emit — передавая имя пользователя в качестве данных.
Теперь нам нужно обработать этот typing event на сервере и для этого изменить метод io.connection в файле index.js, как показано ниже:
В приведенном выше коде мы прослушиваем сокет для события typing. И как только это событие происходит, мы транслируем это событие, вызывая socket.broadcast.emit. Это создает событие typing и отправляет полученные данные всем подключенным клиентам, кроме клиента, отправившего сообщение.
Нам снова нужно обработать это широковещательное сообщение на стороне клиента. А для этого добавьте следующий код под комментарием // Listen for typing message в скрипты index.html:
Из приведенного выше кода каждый клиент прослушивает свой сокет для события typing.
Наконец, обновите очистку feedback, когда пользователь закончит печатать и нажмет «Отправить». Для этого измените метод socket.on под комментарием // Listen for events, как показано ниже:
Теперь, когда событие typing запускается, выводится сообщение, показывающее, что пользователь печатает, как показано ниже:
Заключение
В этой статье мы узнали об API WebSocket — технологии, обеспечивающей двунаправленный поток данных между сервером и клиентом с малой задержкой.
И мы работали с библиотекой Socket.IO, библиотекой JavaScript, которая упрощает настройку WebSockets на клиенте и сервере.
Если вас интересует исходный код созданного нами чат-приложения, вы можете клонировать репозиторий на Github здесь.
Наконец, я надеюсь, что после этого руководства вы узнали достаточно, чтобы использовать WebSockets в своем приложении.
Веб-сокеты в JavaScript очень полезны, поскольку они более эффективны, чем опрос сервера для получения данных. Но чтобы правильно использовать WebSocket API и получить эффективный результат, нужно понимать, как реализовать WebSockets с помощью lSocket.IO API или альтернативной библиотеки Websocket, например WS.
Поэтому, даже если вы чувствуете, что были приняты правильные решения, всегда необходимо убедиться, что это действительно так, и что ваши пользователи хорошо работают с вашим продуктом.
SessionStack использует pub/sub-сервисы для обработки всех полученных поведенческих данных из браузера в режиме реального времени. По мере поступления данных SessionStack позволяет вам просматривать сеансы пользователей в виде видеороликов, что позволяет вам точно видеть, что происходило во время их путешествия.
Сочетая эту визуальную информацию со всеми техническими данными из браузера, такими как ошибки, трассировка стека, сетевые проблемы, данные отладки и т. д., вы можете легко понять проблемные области в своем продукте и эффективно их решить.
Существует бесплатная пробная версия, если вы хотите попробовать SessionStack.
SessionStack, воспроизводящий сеанс
Хотите узнать больше о JavaScript? Ознакомьтесь со всеми публикациями Как работает JavaScript здесь».