Пишем онлайн чат на Websockets используя Swoole / Хабр

Почему swoole?

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

Тем не менее, даже сравнивая с node.js/go/erlang и другими языками, нативно предлагающими асинхронную модель, Swoole — фреймворк написанный на Си и объеденивший в себе низкий порог вхождения и мощную функциональность может быть вполне хорошим кандидатом.

Возможности фреймворка:

Возможные варианты использования:

Примеры кода можно увидеть на

. В разделе документации более подробная информация о всём функционале фреймворка.

Введение в websockets и stomp

— это протокол для двусторонней связи между сервером и клиентом.

Шаг 3: используем php, чтобы создать форму входа.

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

Введение

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

Javascript

Node.js — это серверная технология Javascript, выполняемая сервером в виде PHP, Ruby или Python. JavaScript использует события. Node.js сохраняет эту особенность, поэтому легко создавать асинхронный код.Node.js поставляется с собственным менеджером пакетов: npm.

Javascript-клиент


В этом разделе мы создадим JavaScript-клиента, который будет отправлять сообщения на WebSocket/STOMP-сервер и получать их оттуда.

Мы будем использовать SockJS и Stomp.js для общения с сервером с использованием STOMP over WebSocket.

Jquery

Практически все, что мы собираемся делать с jQuery для обработки наших данных, будет вращаться вокруг запроса на jQuery post.

Php – post.php

На данный момент мы имеем данные POST, отправляемые в файл post.php каждый раз, когда пользователь отправляет форму и посылает новое сообщение. Наша задача теперь захватить эти данные и записать их в лог нашего чата.

Websockets and socket.io

WebSockets — это протокол, который обеспечивает двусторонний синхронный обмен между клиентом и сервером.

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

В WebSockets сервер может отправлять данные клиенту, но клиент тоже может! WebSocket — это своего рода канал связи, открытый в двух направлениях.

Socket.io — это библиотека, основанная на этом протоколе, чтобы упростить использование WebSockets.

Автопрокрутка

Как мы, возможно, видели в других приложениях чатов, содержимое автоматически прокручивается вниз, если контейнер лога чата (#chatbox) переполняется. Мы воплотим простую и похожую возможность, которая будет сравнивать высоту полосы прокрутки контейнера до и после того, как мы выполним ajax запрос.

Архитектура

Пишем онлайн чат на Websockets используя Swoole / Хабр

Архитектура приложения

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

Сервер будет обрабатываться node.js, чтобы выполнить всю разработку (запустить пакеты и веб-сайт). Этот код не будет виден клиенту.Клиентская часть будет загружена на компьютер клиента. Он будет иметь прямой доступ к файлам (html / css и js).

Генерация chatid

Для каждой беседы между двумя пользователями мы создаем чат-комнату и для ее идентификации генерируем уникальный

chatId

Класс ChatRoom выглядит следующим образом:

public class ChatRoom {
    private String id;
    private String chatId;
    private String senderId;
    private String recipientId;
}


Значение

chatId

равно конкатенации

senderId_recipientId

. Для каждой беседы мы сохраняем две сущности с одинаковыми

chatId

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

chatId

Давайте добавим цвета к пользователям

Когда пользователь отправляет сообщение к нему будет привязываться определенный цвет, это мы сделаем следующим образом:

После рефакторигнга получится такой результат:

Закончили

Мы закончили! Я надеюсь, что вы изучили, как работает базовая система чата, и, если у вас есть какие-либо пожелания, я с радостью их приветствую. Это максимально простая система чата, которую вы можете создать как приложение чата. Вы можете оттолкнуться от нее и построить множественные чат комнаты, добавить админку, эмотиконы и т.д. Здесь ваш предел – это небо.

Ниже привожу несколько ссылок, которые вы возможно захотите посмотреть, если задумаетесь о расширении этого приложения чата:

Запрос jquery.ajax

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

Мы завернем наш ajax запрос в функцию. Вы увидите, зачем, прямо сейчас. Как вы можете видеть выше, мы использовали только три из объектов запроса jQuery ajax.

  • url: Строка URL для запроса. Мы используем имя файла лога нашего чата log.html.
  • cache: Это предотвратит кэширование нашего файла. Это обеспечит нам то, что всегда, когда мы посылаем запрос, мы будем иметь обновленный лог чата.
  • sucess: Это позволит нам прикрепить функцию, которая передаст запрошенные нами данные.

Как вы видите, затем мы перемещаем запрошенные нами данные (html) в блок #chatbox div.

Клиентская часть

Нам просто нужно изменить строку в нашем app.js. Фактически, мы не хотим отображать сообщение «Hello world», а реальное окно с окном чата, входами для ввода имени пользователя / сообщения и кнопкой отправки. Для этого мы должны отобразить html-файл (в нашем случае это будет файл ejs) при доступе к корню «/».Поэтому вам нужно применить метод рендеринга к объекту res.

С другой стороны, вам нужно будет создать папку views с файлом index.ejs. CSS будет в общей папке.

Наш localhost: 3000 будет выглядеть так:

Итак, теперь, когда у нас есть наш базовый шаблон, мы должны «установить» socket.io на каждом клиенте, который попытается подключиться к нашему серверу. Для этого нам нужно импортировать библиотеку socket.io на стороне клиента:

Модель сообщения


Первое, о чем нужно подумать — это модель сообщения.

выглядит следующим образом:

public class ChatMessage {
   @Id
   private String id;
   private String chatId;
   private String senderId;
   private String recipientId;
   private String senderName;
   private String recipientName;
   private String content;
   private Date timestamp;
   private MessageStatus status;
}

Класс

ChatMessage

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

В нем также есть поле статуса, указывающее доставлено ли сообщение клиенту.

public enum MessageStatus {
    RECEIVED, DELIVERED
}

Когда сервер получает сообщение из чата, он не отправляет сообщение адресату напрямую, а отправляет уведомление (

), чтобы оповестить клиента о получении нового сообщения. После этого клиент сам может получить новое сообщение. Как только клиент получит сообщение, оно помечается как доставленное (DELIVERED).

Уведомление выглядит следующим образом:

public class ChatNotification {
    private String id;
    private String senderId;
    private String senderName;
}

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

Настройка websocket и stomp в spring

Первым делом настраиваем конечную точку STOMP и брокер сообщений.

Для этого создаем класс WebSocketConfig с аннотациями @Configuration и @EnableWebSocketMessageBroker.

Настройка среды разработки

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

Итак, теперь мы готовы установить пакеты, необходимые для разработки нашего приложения чата! Нам понадобятся эти пакеты:

Чтобы установить их в нашей среде, это очень просто:

$ npm install --save package_name

В вашем package.json вы можете добавить эту строку в ключ скриптов:In your package.json, you could add this line into your scripts key:

“start”: “nodemon app”

С этой командой мы можем запустить nodemon.

$ npm run start

Теперь все готово и мы можем приступать к разработке.

Пользователь

Когда пользователь подключается к нашему приложению, мы устанавливаем ему / ей имя пользователя по умолчанию, например «анонимный». Для этого нам нужно перейти на серверную часть (app.js) и добавить ключ в сокет. На самом деле, сокет представляет каждого клиента, подключенного к нашему серверу.

Постоянное обновление лога чата

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

Ответ на наш вопрос находится в функции setInterval. Эта функция будет запускать нашу функцию loadLog() каждые 2,5 секунды, которая будет запрашивать обновленный файл и делать автопрокрутку блока.

Приветствие и меню выхода из системы

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

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

Приступим к использованию


Ниже я опишу процесс написания несложного Websocket сервера для онлайн-чата и возможные при этом затруднения.

Перед тем как начать: Более подробная информация о классах swoole_websocket_server и swoole_server (Второй класс наследуется от первого).Исходники самого чата.

Для использования автокомплита в IDE предлагается использовать

Минимальный шаблон Websocket-сервера:

Разработка чата


Теперь мы можем приступать у разработке, но перед этим, надо создать .js-файл в директории проекта

«chat.js»

в чем мы и будем писать наш чат. Для начала открываем наш

chat.js

и подключаем все модули таким образом:

Резюме

Мне кажется, что Swoole очень активно развивался последний год, вышел из стадии когда его можно было назвать «сырым», и теперь вполне составляет конкуренцию использованию node.js/go с точки зрения асинхронного программирования и реализации сетевых протоколов.

Буду рад услышать различные мнения по теме и отзывы от тех кто уже имеет опыт использования Swoole

Пообщаться в описанном чатике можно по ссылкеИсходники доступны на Github.

Серверная часть:

Мы должны создать файл app.js, который запустит наш сервер и все пакеты.

Создание простого приложения для чата с помощью node.js и socket.io

Чтобы разработать приложение реального чата, мы должны внедрить систему отправки / получения данных в режиме реального времени. Это будет невозможно сделать с помощью реляционной базы данных и Ajax-вызовов. Благодаря WebSocket и библиотеке socket.io это становится легко.

Вы можете следовать этому уроку с моим репозиторием Github:

Сообщение

Для сообщений это тот же принцип!

chat.js:

app.js:

Для события new_message вы можете видеть, что мы вызываем свойство sockets для io. Он представляет все подключенные розетки. Таким образом, эта строка фактически отправит сообщение всем сокетам. Мы хотим, чтобы это показывало сообщение, отправленное пользователем всем (и само по себе).

Вот окончательный результат нашего чата:

Для крутости нашего приложения добавим некоторые улучшения, теперь когда кто то будет печатать сообщение мы увидим это

Добавить это будет легко:

После добавления элемента HTML в наш index.ejs мы просто добавляем прослушиватель событий jQuery при вводе и отправляем событие сокета с именем typing.

С другой стороны, мы слушаем набор текста и транслируем сообщение. Вещание означает отправку сообщения всем, кроме сокета, который его запускает.

Установка дополнительных модулей

Вам понадобятся также такие модули как:

Установка модуля


Итак, давайте приступать?! Для начала нам нужно собственно установить наш

, как его установить можете прочитать

, а для тех, кто не понял, поясню: есть

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

, на сервер нужно поставить сам модуль через

npm

в папку проекта (для этого надо заранее открыть её в консоли, а дальше устанавливать):

npm install socket.io --save


После того как установили модуль, в папке с проектом (

куда ставили

) появится папка

«node_modules»

Теперь мы должны установить сам .js файл модуля в папку с проектом (.js файл будет использоваться на клиенте), ставить отсюда => *тык*. Вы скачаете архив, и оттуда вы должны достать файл «socket.io.js» и перекинуть в папку с проектом.

Для тех кто не понял, структура папки проекта с чатом должна быть такова на данный момент:

chat: (Сама папка)
|node_modules
|--socket.io (Внутри <i>node_modules</i>)
|socket.io.js


После того как вы скачали .js файл и установили модуль — можно приступать к следующему этапу.

Шаг 1: html разметка

Мы начнем этот урок с создания нашего первого файла index.php.

Шаг 4: поддержка пользовательского ввода данных

После того, как пользователь подтвердил свои действия в нашей форме, нам нужно захватывать его ввод с клавиатуры и писать его в лог нашего чата. Для того, чтобы сделать это, мы должны использовать jQuery и PHP, чтобы работать синхронно на стороне сервера и на стороне клиента.

Шаг 5: отображение содержимого лога чата (log.html)

Все, что пользователь разместил, обработано и опубликовано с помощью jQuery; оно записано в лог чата с помощью PHP. Единственное, что осталось сделать – это показать обновленный лог чата пользователю.

Чтобы сэкономить нам немного времени, мы предварительно загрузим лог чата в блок #chatbox div, как если бы он что-то содержал.

Заключение

В этой статье мы рассмотрели все важные моменты создания чата с использованием Spring Boot и STOMP over WebSocket.

Мы также создали JavaScript-клиент с применением библиотек SockJs и Stomp.js.

Пример исходного кода можно найти здесь.

Похожее:  Add Authentication to Your Vanilla JavaScript App in 20 Minutes | Okta Developer

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *