Socket.io — это библиотека javascript, которая помогает нам создавать веб-приложения в реальном времени, такие как чаты и многопользовательские игры, без необходимости иметь дело со всей сложностью веб-сокетов.

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

На веб-сайте socket.io в учебнике «Начало работы» показано, как создать базовый веб-чат в реальном времени за несколько шагов. Я сделаю то же самое здесь, попытавшись охватить все детали и добавив некоторые более продвинутые функции, такие как представление в реальном времени количества подключенных клиентов и базовое сохранение данных, чтобы приложение могло распознавать пользователей, когда они перезагружают приложение.

Живая демонстрация доказательства концепции доступна здесь:
https://easy-chat-web-app.herokuapp.com/

А вот и репозиторий: https://github.com/lamorbidamacchina/easychat

Что нужно для начала?

Хорошее знание Html, Css и Javascript, а также некоторые базовые знания NodeJs и Git полезны для полного понимания проекта, который мы собираемся разработать.

У вас уже должен быть установлен NodeJS на вашем локальном компьютере. Если нет, начните отсюда.

Использование VS Code в качестве редактора кода рекомендуется, но не обязательно.

В конце этой статьи я кратко объясню, как развернуть проект в Интернете с помощью Heroku, платформы облачных приложений, которая отлично работает и бесплатна (для базового некоммерческого использования).

Хорошо, давайте начнем…

Базовая настройка приложения узла

Прежде всего, давайте создадим новую папку, куда мы поместим наш код. Я назову свой «mychat», но вы можете выбрать любое имя, которое вам нравится. После создания давайте войдем в папку и запустим npm init, чтобы инициализировать базовое приложение NodeJs.
В macOs я открываю Терминал и набираю

> mkdir mychat
> cd mychat
> npm init

Появится утилита командной строки, которая задаст вам несколько простых вопросов. Вы можете оставить все пустым (нажмите Enter), но я предлагаю вам заполнить app.js, когда утилита запросит точку входа.

Имя точки входа важно, потому что позже нам нужно будет настроить ее на нашем рабочем сервере в Heroku.

Теперь мы можем открыть наш редактор кода. Если вы используете VS Code, мы можем сделать это, просто набрав

> code .

Вы заметите, что теперь наша папка содержит файл с именем package.json. Этот файл содержит некоторую базовую информацию о нашем приложении Node.

Давайте создадим новый файл app.js и добавим базовый код для создания простого веб-сервера.

Для создания нашего сервера мы полагаемся на Express, который представляет собой полезную среду NodeJS, которая помогает нам создать базовое веб-приложение с очень небольшим количеством строк кода. К настоящему моменту мы в основном создаем очень простой веб-сервер, прослушивающий порт 3001 (или порт, указанный в файле .env, которого у нас пока нет), обслуживающий html-файл с именем default.html, расположенный в папке /public.

Поскольку мы используем Express, нам нужно установить его как зависимость в нашем проекте node перед запуском нашего веб-сервера. Чтобы установить Express framework, откройте Терминал и введите

> npm install express --save

После завершения процесса установки вы заметите, что в каталоге нашего проекта появилась новая папка /node_modules. Нет необходимости включать эту папку в наш репозиторий git, поэтому я предлагаю создать файл .gitignore, чтобы избежать управления версиями /node_modules.

Затем давайте создадим папку /public и файл default.html, в котором будет написано только «hello world».

Чтобы легко запустить наш сервер, нам нужно отредактировать package.json и добавить строку под «test».

Таким образом, как только мы откроем Терминал и введем npm start, NodeJS выполнит app.js, и это запустит наш веб-сервер на http://localhost:3001.

Теперь мы можем открыть наш браузер на http://localhost:3001, и мы должны увидеть это:

Это означает, что наш веб-сервер работает правильно, и мы можем начать создавать чат в реальном времени с помощью socket.io!

Для тех из вас, у кого нет опыта работы с Node, Ctrl+c в Терминале остановит наш сервер.

Добавьте пользовательский интерфейс

Давайте создадим базовый интерфейс для нашего чата. Вы можете создавать любые наборы, которые вам нравятся, но для начала я предлагаю скачать контент, который я положил в папку /public, здесь: https://github.com/lamorbidamacchina/easychat/tree/main/public

Короче говоря, у нас есть HTML-шаблон на основе начальной загрузки в default.html, связанный с внешним файлом css с именем default.css, и еще несколько файлов js в /lib. , в основном библиотеки jQuery и Socket.io. Нам также нужен файл default.js, который будет управлять взаимодействием нашего веб-чата на стороне клиента, и который мы проанализируем дальше. Сейчас просто удалите все содержимое в default.js или удалите его и создайте пустой файл.

Если мы снова запустим наш сервер с помощью npm start и укажем в браузере http://localhost:3001, мы должны увидеть что-то похожее на это:

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

Добавьте веб-чат в реальном времени

Чтобы это заработало, нам нужно написать некоторый код в default.js, чтобы отправлять и получать сообщения и формировать сервер, и еще немного кода в app.js, получать и отправлять сообщения от и к клиентам.

Начнем с простого примера. Каждый раз, когда какой-либо пользователь нажимает на интерфейс, давайте отправим сообщение «hello world» на наш сервер Socket.io и зарегистрируем его.

Для этого мы можем отредактировать default.js следующим образом:

В app.js мы можем отредактировать код следующим образом:

Теперь, прежде чем перезапустить наш сервер и проверить, все ли работает правильно, так как нам нужно добавить зависимости Socket.io в наш проект.
В Терминале мы можем написать:

npm install socket.io --save

и как только все будет установлено, давайте перезапустим наш сервер и укажем на localhost:3001. Теперь, если я щелкну где-нибудь на странице веб-чата и проверю, что происходит с моим сервером, я увижу этот журнал:

Здесь происходят две интересные вещи. Когда я открываю страницу, сервер может зарегистрировать новое соединение (l.10 из app.js). Более того, всякий раз, когда сервер получает сокетное соединение с именем «сообщение», он отображает его содержимое (11–13 из app.js).
Откуда берется это соединение с сокетом под названием «сообщение»? Легкий. Он исходит из socket.emit, который мы поместили в наш клиентский код (1.4 default.js).

Обобщить:

  • мы можем использовать io.on() для прослушивания нового соединения
  • мы можем использовать socket.emit() для отправки контента через сокет
  • мы можем использовать socket.on() для чтения содержимого через сокет

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

Вот новая версия default.js:

  • мы сохраняем случайный идентификатор для каждого нового пользователя, сохраняя его в локальном хранилище (л.6–12). позже мы могли бы обновить код для управления псевдонимом аналогичным образом.
  • мы отправляем значение поля сообщения в сокет «сообщение» вместе с идентификатором пользователя (л.14–22)
  • мы слушаем сокет «сообщение» и обновляем нашу доску чата каждый раз, когда получаем новое сообщение от пользователя, добавляя метку времени (l-24–31)
  • мы слушаем сокет «участники» и обновляем счетчик вверху страницы

Теперь давайте посмотрим, что происходит на стороне сервера в новой версии app.js:

Что следует отметить в app.js:

  • мы можем считывать количество подключенных клиентов каждый раз, когда подключается новый клиент, и отправлять его всем клиентам через сокет с именем «участники» (l.12–14)
  • мы можем прочитать любое сообщение, отправленное через сокет «message», зарегистрировать его и отправить обратно всем подключенным клиентам (l.17–20)
  • мы можем прочитать количество подключенных клиентов каждый раз, когда клиент отключается, и отправить его всем клиентам через сокет «участников» (l.24–29)

Если вы перезапустите свой сервер и подключитесь к https://localhost:3001 из двух разных браузеров, вы должны увидеть, что наш веб-чат в реальном времени работает и работает :)

Давайте разделим наш чат на разные чаты

С socket.io довольно легко настроить разные комнаты, которые в основном представляют собой разные каналы, к которым наши сокеты могут присоединяться или выходить отдельно.

Предположим, мы хотим создать разные чаты, просто добавив параметр к нашему URL-адресу: http://localhost:3001/?room=white должен привести нас к чату с именем, например, белый.
Если я отправлю сообщение в этой комнате, только пользователи, подключенные к этой же комнате, смогут прочитать и ответить на мое сообщение. Как мы это делаем? Нам нужно немного изменить наш код javascript, как на стороне клиента, так и на стороне сервера.

Вот новая версия default.js (кстати, я также добавил некоторый код для назначения разных случайных цветов случайным именам пользователей)

Во-первых, нам нужно прочитать параметр «room» из URL-адреса (строки 6–8) и передать его на наш сервер через событие .emit (строка 22).

Затем каждый раз, когда мы отправляем новое сообщение на наш сервер, мы должны отправлять информацию о том, в какую комнату мы собираемся отправить сообщение (строка 39).

На стороне сервера: обновленная версия app.js.

Прежде всего, мы читаем содержимое нового сокета с именем «room», регистрируем его в консоли и вызываем socket.join() для подписки сокета на данную комнату (строки 12–15).

Теперь давайте рассмотрим строки 25–29. В сокете message мы читаем новое свойство объекта, которое мы только что установили в коде на стороне клиента — obj.room. Вместо того, чтобы рассылать полученное сообщение всем подключенным клиентам, мы отправляем сообщение только в указанную комнату, используя io.to(name-of-the-room).emit().

Вот и все.

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

Опубликовать на Heroku

Heroku предлагает бесплатный облачный сервис, где мы можем легко разместить наше приложение. После регистрации и входа в систему вы можете создать новое приложение:

Как только ваше новое приложение будет настроено с именем и регионом, вы должны загрузить и установить CLI Heroku.

После того, как вы успешно установили Heroku CLI на свой компьютер, вы можете открыть Терминал и ввести

heroku login

Вы должны увидеть это сообщение:

После входа в систему вы должны ввести эту команду, где NAME_OF_THE_APP — это имя, которое вы ранее выбрали для своего приложения на Heroku:

heroku features:enable http-session-affinity -a NAME_OF_THE_APP

Как указано на их странице документации, эта команда включает липкие сеансы, которые нам нужны, чтобы наш чат работал на Heroku.

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

Я решил подключить свой GitHub, где я ранее создал репозиторий с именем «easychat», к моему приложению на Heroku.

Если вы не хотите настраивать свой репозиторий на Heroku, вы можете выбрать другой вариант на панели Метод развертывания.

Если вы прокрутите ту же страницу вниз, вы сможете выбрать, включать ли автоматическое развертывание каждый раз, когда выполняется новая отправка в ветку Main, или отключить его и управлять своими развертываниями вручную.

Нажав «Открыть приложение» в верхней части той же страницы, вы сможете увидеть, как ваш веб-чат в реальном времени работает и полностью доступен для всех и везде.

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

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

Вот краткий список дополнений, которые я хотел бы разработать, когда у меня будет время:

  • Добавьте настраиваемые псевдонимы и цвета вместо случайных строк для пользователей.
  • Добавить смайлики
  • Добавьте функцию для создания разных чатов
  • Добавить чаты один к одному
  • Добавить сквозное шифрование