Создание приложения для общения в реальном времени с помощью React, Laravel и WebSockets

Вы каждый день пользуетесь коммуникациями в реальном времени. Это одновременный обмен информацией между отправителем и получателем с почти нулевой задержкой. Интернет, стационарные телефоны, мобильные/сотовые телефоны, мгновенный обмен сообщениями (IM), интернет-релейный чат, видеоконференции, телеконференции и роботизированное телеприсутствие — все это примеры систем связи в реальном времени.

В этом руководстве вы узнаете, как создать приложение для публичного чата в реальном времени с помощью React.js, Laravel и Ably. Вы будете использовать React.js для создания фронтенда/UI и Laravel для взаимодействия с API Ably Realtime для обеспечения общения в реальном времени. Любой человек в Интернете сможет использовать это приложение для публикации сообщений в публичном чате и анонимного общения с другими пользователями. Создавая подобное приложение, вы узнаете о соответствующих концепциях для создания приложений, требующих передачи данных в реальном времени.

Весь код проекта доступен в этом репозитории GitHub.

Архитектура приложения для чата в реальном времени

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

React.js

React.js — это библиотека JavaScript с открытым исходным кодом, которая используется для построения реактивных пользовательских интерфейсов и часто применяется для создания одностраничных приложений с рендерингом на стороне клиента. Ее очень легко интегрировать с TypeScript. На основе этого руководства вы также можете выполнить тот же набор действий в Next.js, который представляет собой мета-фреймворк для разработки универсальных приложений React.js, рендеримых как на стороне клиента, так и на стороне сервера.

Laravel

Laravel — это фреймворк веб-приложений на основе PHP с выразительным и элегантным синтаксисом. Сообщество веб-разработчиков любит Laravel, потому что он обеспечивает потрясающий опыт разработчика и поддерживает передовые концепции, такие как очереди, внедрение зависимостей, модульное тестирование и интеграционное тестирование. Laravel — отличный выбор для создания приложений реального времени, и он уже поставляется с поддержкой Ably для «трансляции» событий Laravel на стороне сервера через WebSocket-соединение.

Ably

Ably — это платформа обмена сообщениями pub/sub, которая обеспечивает синхронизацию цифрового опыта в реальном времени для миллионов одновременно подключенных устройств по всему миру. Ably предлагает WebSockets, возобновление потока, историю, присутствие и управляемые сторонние интеграции, чтобы упростить создание, расширение и доставку цифрового опыта реального времени в масштабе.

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

Настройка учетной записи Ably

Для начала вам нужно создать учетную запись Ably, если у вас ее нет.

Затем вам нужно получить API-ключ с панели Ably:

1. Перейдите на панель приложений и нажмите кнопку Создать новое приложение.

2. Скопируйте закрытый ключ API после того, как приложение будет создано. Сохраните ключ; вы будете использовать его для аутентификации в сервисе Ably в Laravel и React.js.

3. Включите поддержку протокола Pusher в настройках приложения Ably, чтобы использовать протокол Pusher с Ably. Вы можете найти эту функцию в настройках адаптера протокола на вкладке «Настройки». Если вас спросят о создании пространств имен по умолчанию, нажмите Нет, спасибо.

Вот и все. Ваш аккаунт Ably готов к поддержке обмена сообщениями в реальном времени.

Настройка среды

Вот что вам понадобится для начала работы.

Предварительные условия

— Node.js: В этом учебнике используется Node v16.14.0

— PHP: В этом учебнике используется PHP v7.4.3

— Composer: В этом руководстве используется Composer v2.1.0

Настройка проекта

Вам понадобится основной каталог, в котором будет храниться код для фронтенда (React.js) и бэкенда (Laravel). Откройте терминал, перейдите по выбранному пути и создайте каталог chat-app-react-laravel-ably, выполнив следующую команду:

mkdir chat-app-react-laravel-ably
Войти в полноэкранный режим Выйти из полноэкранного режима

В директории chat-app-react-laravel-ably вы установите проекты Laravel и React.js.

Настройка бэкенда

Начните со сборки бэкенда приложения для чата.

Затем в терминале выполните следующую команду, чтобы создать проект Laravel в каталоге backend:

composer create-project laravel/laravel backend
Войти в полноэкранный режим Выйти из полноэкранного режима

Далее, после выполнения вышеуказанной команды, запустите свой проект Laravel, выполнив в терминале следующие команды:

cd backend
php artisan serve
Войти в полноэкранный режим Выйти из полноэкранного режима

Наконец, откройте localhost:8000 в браузере, и вы увидите, что ваш проект Laravel запущен:

Настройка вещания

Перед трансляцией событий вам необходимо зарегистрировать AppProvidersBroadcastServiceProvider. Для этого откройте файл config/app.php и откомментируйте BroadcastServiceProvider в массиве providers:

'providers' => [
...
AppProvidersBroadcastServiceProvider::class,
...
]
Вход в полноэкранный режим Выход из полноэкранного режима

Этот класс BroadcastServiceProvider содержит необходимый код для регистрации маршрутов авторизации трансляции и обратных вызовов.

Далее, поскольку вы хотите транслировать события с помощью Ably, установите Ably PHP SDK, выполнив следующую команду в терминале:

composer require ably/ably-php
Войти в полноэкранный режим Выйти из полноэкранного режима

Вы также должны настроить учетные данные Ably в файле config/broadcasting.php. Пример конфигурации Ably уже включен в этот файл, что позволит вам быстро указать ваш ключ.

Затем добавьте переменную окружения ABLY_KEY в файл .env и замените your-ably-key на ключ вашего зарегистрированного приложения Ably из панели управления Ably:

ABLY_KEY=your-ably-key
Вход в полноэкранный режим Выйти из полноэкранного режима

Наконец, измените драйвер трансляции (BROADCAST_DRIVER) на ably в файле .env:

BROADCAST_DRIVER=ably
Войти в полноэкранный режим Выйдите из полноэкранного режима

Теперь ваш проект Laravel готов к началу трансляции событий.

Трансляция событий в Laravel с помощью WebSockets

Прежде чем писать код для трансляции событий на ваш фронтенд React.js, важно знать, как работает трансляция в Laravel.

Трансляция событий в Laravel позволяет вам транслировать события на стороне сервера в приложение на стороне клиента, используя подход WebSocket на основе драйверов. Вы можете потреблять эти события на стороне клиента с помощью пакета Laravel Echo npm.

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

Чтобы отправлять события из Laravel, создайте файл событий, выполнив в терминале следующую команду:

php artisan make:event MessageEvent
Войти в полноэкранный режим Выйти из полноэкранного режима

Эта команда создаст файл MessageEvent.php в директории app/Events.

Далее откройте файл app/Events/MessageEvent.php и замените его содержимое следующим кодом:

<?php
namespace AppEvents;
use IlluminateBroadcastingChannel;
use IlluminateBroadcastingInteractsWithSockets;
use IlluminateBroadcastingPresenceChannel;
use IlluminateBroadcastingPrivateChannel;
use IlluminateContractsBroadcastingShouldBroadcast;
use IlluminateFoundationEventsDispatchable;
use IlluminateQueueSerializesModels;
use IlluminateSupportStr;
// 1
class MessageEvent implements ShouldBroadcast
{
use Dispatchable, InteractsWithSockets, SerializesModels;
private $user, $message;
// 2
public function __construct($user, $message)
{
$this->user = $user;
$this->message = $message;
}
// 3
public function broadcastWith()
{
return [
'id' => Str::orderedUuid(),
'user' => $this->user,
'message' => $this->message,
'createdAt' => now()->toDateTimeString(),
];
}
// 4
public function broadcastAs()
{
return 'message.new';
}
// 5
public function broadcastOn()
{
return new Channel('public.room');
}
}
Вход в полноэкранный режим Выйти из полноэкранного режима

Ниже приведены особенности вышеуказанного кода:

1. Вы определяете класс MessageEvent, который реализует интерфейс ShouldBroadcast.

2. Вы определяете конструктор (__construct) для класса MessageEvent, которому вы передадите переменные user ($user) и message $message) при создании объекта события MessageEvent.

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

4. Вы указываете имя трансляции как message.new, определяя метод broadcastAs. Этот метод не требуется, поскольку по умолчанию Laravel транслирует событие, используя имя класса события.

5. Вы определяете метод broadcastOn, который отвечает за возврат каналов, на которых должно транслироваться событие. В данном случае событие будет транслироваться на публичный канал (Channel) с именем public.room. Если вы хотите транслировать событие на частном канале, вы используете PrivateChannel вместо Channel.

Получение запросов от фронтенда React.js

В этом проекте приложения для чата фронтенд отправляет POST-запрос на бэкенд Laravel. Получив запрос, Laravel запустит событие MessageEvent и передаст его в эфир с помощью указанного Ably широковещательного драйвера.

Чтобы получать API-запросы с фронтенда, откройте файл routes/api.php и замените его содержимое следующим кодом:

<?php
use IlluminateHttpRequest;
use IlluminateSupportFacadesRoute;
use AppEventsMessageEvent;
// 1
Route::post('new-message', function (Request $request) {
// 2
event(new MessageEvent($request->user, $request->message));
return 'ok';
});
Вход в полноэкранный режим Выйти из полноэкранного режима

В приведенном выше коде есть следующие особенности:

1. Вы определяете маршрут API (new-message), на который вы сможете отправлять POST-запросы. Этот маршрут API будет доступен по адресу localhost:8000/api/new-message].

2. Вы вызываете событие MessageEvent, передавая в качестве аргументов переменные user ($request->user) и message ($request->message).

Наконец, чтобы проверить, правильно ли работает код, попробуйте отправить POST-запрос на конечную точку localhost:8000/api/new-message с помощью Postman или любого другого инструмента и отправить user и message в качестве полезной нагрузки. Вы должны получить ответ ok. Если вы не получили ответ ok, внимательно изучите шаги руководства, чтобы убедиться, что вы следовали им правильно.

Это все для Laravel-части проекта. Далее необходимо настроить приложение React.js для прослушивания событий, транслируемых бэкендом Laravel.

Настройка фронтенда React.js

Теперь, когда вы полностью настроили свой проект Laravel, пришло время создать приложение React.js frontend.

Поскольку ваше текущее окно терминала обслуживает проект Laravel, откройте другое окно терминала и выполните следующую команду из корневого каталога проекта (chat-app-react-laravel-ably), чтобы создать проект React.js с помощью известной команды create-react-app:

npx create-react-app frontend
Войти в полноэкранный режим Выйти из полноэкранного режима

Наконец, после завершения установки перейдите в каталог frontend и запустите сервер разработки React.js, выполнив следующие команды в терминале:

cd frontend
npm start
Войти в полноэкранный режим Выйти из полноэкранного режима

Эта команда запустит сервер разработки на порту 3000 и приведет вас на localhost:3000. Первый вид веб-сайта React.js будет выглядеть следующим образом:

Установка пакетов фронтенда

Для создания фронтенда приложения чата вам потребуется установить следующие пакеты:

— axios: Этот пакет позволяет выполнять HTTP-запросы в приложении на стороне клиента.

— Laravel Echo: Эта библиотека JavaScript позволяет вам подписываться на каналы и слушать события, транслируемые вашим серверным драйвером вещания.

— pusher-js: Вы можете подумать: «Зачем мне нужен pusher-js, если я использую Ably для трансляции событий?». Это потому, что Ably включает адаптер протокола Pusher, который позволяет вам использовать протокол Pusher при прослушивании событий в вашем клиентском приложении.

Выключите сервер разработки React.js, нажав Control-C, а затем выполните следующую команду, чтобы установить необходимые модули для вашего приложения React.js:

npm install axios laravel-echo pusher-js
Войти в полноэкранный режим Выйти из полноэкранного режима

После завершения установки добавьте переменную окружения REACT_APP_MIX_ABLY_PUBLIC_KEY в файл .env. Ваш открытый ключ Ably — это часть вашего ключа Ably, которая находится перед символом ::

REACT_APP_MIX_ABLY_PUBLIC_KEY=<your-ably-public-key>
REACT_APP_API_BASE_URL=http://localhost:8000/api
Вход в полноэкранный режим Выйти из полноэкранного режима

В приведенной выше конфигурации вы указали REACT_APP_MIX_ABLY_PUBLIC_KEY и REACT_APP_API_BASE_URL. Важно префикс переменных окружения REACT_APP_, чтобы они могли быть использованы create-react-app.

Настройка Laravel Echo

Вы должны настроить Laravel Echo, прежде чем он поможет вам подписываться на каналы и прослушивать события. Откройте файл src/App.js и введите следующий код:

// 1
import PublicMessagesPage from './components/PublicMessagesPage';
// 2
export default function App() {
return <PublicMessagesPage />;
}
Вход в полноэкранный режим Выйти из полноэкранного режима

В приведенном выше коде происходит следующее:

1. Вы импортируете компонент PublicMessagesPage.

2. Вы рендерите компонент PublicMessagesPage в компоненте App.

Создание пользовательского интерфейса фронтенда

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

Создание главной страницы публичного чата

Для начала создайте каталог components в каталоге src. Затем в каталоге components создайте файл PublicMessagesPage.js и добавьте в него следующий код:

// 1
import React, { useState, useEffect } from 'react';
import Axios from 'axios';
import Echo from 'laravel-echo';
import Pusher from 'pusher-js';
import Messagebox from './Messagebox';
// 2
export default function PublicMessagesPage() {
// 3
const [user, setUser] = useState('');
const [message, setMessage] = useState('');
const [messages, setMessages] = useState([]);
async function handleSendMessage(e) {
// TODO
}
// 4
return (
<div>
<div>
<div>
<h1>Public Space</h1>
<p>Post your random thoughts for the world to see</p>
</div>
<div>
{messages.map((message) => (
<Messagebox key={message.id} message={message} />
))}
</div>
<div>
<form onSubmit={(e) => handleSendMessage(e)}>
<input
type="text"
placeholder="Set your username"
value={user}
onChange={(e) => setUser(e.target.value)}
required
/>
<div>
<input
type="text"
placeholder="Type your message..."
value={message}
onChange={(e) => setMessage(e.target.value)}
required
/>
<button onClick={(e) => handleSendMessage(e)}>Send</button>
</div>
</form>
</div>
</div>
</div>
);
}
Вход в полноэкранный режим Выход из полноэкранного режима

Вот что происходит в приведенном выше коде:

1. Вы импортируете необходимые пакеты NPM.

2. Вы определяете функциональный компонент PublicMessagesPage.

3. Вы определяете переменные state для компонента PublicMessagesPage, используя useState React hook:

user хранит имя текущего пользователя

message хранит текущее набранное сообщение

messages хранит все сообщения, отправленные и полученные в текущей сессии

4. Вы возвращаете JSX-шаблон для страницы публичных сообщений.

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

Далее необходимо реализовать компонент Messagebox.

Создание компонента окна сообщений

Для начала в директории components создайте файл Messagebox.js и добавьте в него следующий код:

// 1
export default function Messagebox({ message }) {
const formatDate = (value) => {
if (!value) return '';
return new Date(value).toLocalTimeString();
};
// 2
return (
<div>
<div>
<p>
<b>{message.user}</b>
</p>
<p>{message.message}</p>
<p>{formatDate(message.createdAt)}</p>
</div>
</div>
);
}
Вход в полноэкранный режим Выйти из полноэкранного режима

Вот особенности вышеприведенного кода:

1. Вы определяете функциональный компонент без состояния Messagebox и передаете ему в качестве параметра объект message.

2. Вы возвращаете HTML-шаблон для компонента Messagebox.

На этом этапе сохраните свой прогресс и перезапустите сервер разработки React.js, выполнив в терминале следующую команду:

npm start
Войти в полноэкранный режим Выйти из полноэкранного режима

Зайдите на localhost:3000, и, судя по тому, как вы оформили свое приложение, вы получите что-то вроде этого:

Отправка сообщений

После создания внешнего пользовательского интерфейса следующим шагом будет включение отправки сообщений. В файле src/components/PublicMessagesPage.js необходимо реализовать метод handleSendMessage. Поэтому начните с обновления функции handleSendMessage, добавив следующий код:

async handleSendMessage(e) {
// 1
e.preventDefault();
// 2
if (!user) {
alert('Please add your username');
return;
}
// 3
if (!message) {
alert('Please add a message');
return;
}
try {
// 4
await Axios.post('/new-message', {
user: user,
message: message,
});
} catch (error) {
console.error(error);
}
}
Вход в полноэкранный режим Выйти из полноэкранного режима

Вот особенности вышеприведенного кода:

1. Вы используете метод e.preventDefault(), чтобы предотвратить перезагрузку страницы при отправке формы.

2. Вы проверяете, пуста ли переменная состояния user. Если она пуста, вы предупреждаете пользователя о необходимости добавить свое имя пользователя.

3. Вы также проверяете, пуста ли переменная состояния message. Если она пуста, вы предупреждаете пользователя о необходимости добавить сообщение.

4. Вы делаете POST-запрос (Axios.post) к конечной точке API /new-message после успешной проверки и отправляете переменные состояния user и message в качестве полезной нагрузки.

Как только POST-запрос будет сделан к конечной точке Laravel, произойдет событие MessageEvent. Далее вам нужно прослушать это событие в вашем приложении React.js.

Прослушивание событий

Чтобы прослушивать события, добавьте React-хук useEffect к компоненту PublicMessagesPage в файле src/components/PublicMessagesPage.js:

// 1
useEffect(() => {
// 2
Axios.defaults.baseURL = process.env.REACT_APP_API_BASE_URL;
// 3
const echo = new Echo({
broadcaster: 'pusher',
key: process.env.REACT_APP_MIX_ABLY_PUBLIC_KEY,
wsHost: 'realtime-pusher.ably.io',
wsPort: 443,
disableStats: true,
encrypted: true,
});
// 4
echo
.channel('public.room')
.subscribed(() => {
console.log('You are subscribed');
})
// 5
.listen('.message.new', (data) => {
// 6
setMessages((oldMessages) => [...oldMessages, data]);
setMessage('');
});
}, []);
Вход в полноэкранный режим Выход из полноэкранного режима

В приведенном выше коде есть следующие особенности:

1. Вы определяете React-хук useEffect, который вызывается сразу после установки компонента PublicMessagesPage.

2. Вы определяете базовый URL (Axios.defaults.baseURL) для пакета Axios, по которому он выполняет HTTP-запросы к API бэкенда.

3. Вы создаете новый экземпляр Echo и подписываетесь на канал public.room на бэкенде.

4. Вы подписываетесь на публичный канал (public.room), на котором транслируются события.

5. Вы слушаете событие message.new и передаете функцию обратного вызова, которая получает data, отправленные в качестве ответа на событие. Поскольку вы определили пользовательское имя трансляции с помощью метода broadcastAs, вам необходимо добавить символ . перед именем события. Это добавление указывает Echo не добавлять пространство имен приложения к имени события.

5. Обновите переменную состояния messages, добавив новую полезную нагрузку сообщения (data) к существующим сообщениям (oldMessages) в состоянии.

Наконец, сохраните свой прогресс и перезагрузите сервер разработки React.js. Теперь вы сможете отправлять сообщения в публичный чат:

Тестирование приложения

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

Заключение

Вот и все! В этом руководстве вы узнали, как создать приложение для чата в реальном времени с помощью React.js, Laravel и Ably. Вы также проверили, правильно ли работает ваше приложение. В зависимости от ваших требований, вы можете узнать, как добавить больше функций в ваше приложение чата в потрясающей документации Ably. Очень интересно узнать о том, как вы будете использовать Ably в своих приложениях.

Весь исходный код этого руководства доступен в этом репозитории GitHub.

Оцените статью
devanswers.ru
Добавить комментарий