Найти в Дзене
Computer Pro

Простейший веб-чат на Fastapi + Websocket

Однажды, мне попалось видео по организации вебчата на Fastapi и Websocket, ну я как прилежный ученик решил всё это повторить, слово в слово в коде. И у меня конечно же ничего не заработало. Я понял что у меня не хватает знаний по JavaScript (я вообще ничего в этом языке не знал), пришлось подтянуть базовые знания в этой штуке и только после этого вернуться к вебчату... Когда я прошел некую базу по JS, я понял что надо бы полностью переписать тот код что я увидел в видео. Основываясь на документации Fastapi по вебсокетам, можно запустить самый примитив. Который покажет как работают вебсокеты, но это будет не самый красивый вариант кода. Нужно как минимум разделять фронтенд и бэкенд, а тут все в кучу: Но, запустив данный код, мы можем посмотреть как можно написать простейший веб-чат: Сделаем так чтобы шаблон HTML находился в директории templates, код JS в отдельном файле и директории static, плюс консоль разработчика браузера постоянно ругается на отсутствующий файл favicon.ico, пропишем
Оглавление
Картинка для карточки. Фото автора.
Картинка для карточки. Фото автора.

Однажды, мне попалось видео по организации вебчата на Fastapi и Websocket, ну я как прилежный ученик решил всё это повторить, слово в слово в коде. И у меня конечно же ничего не заработало. Я понял что у меня не хватает знаний по JavaScript (я вообще ничего в этом языке не знал), пришлось подтянуть базовые знания в этой штуке и только после этого вернуться к вебчату...

Базовый вариант чата

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

скриншот из документации...
скриншот из документации...

Но, запустив данный код, мы можем посмотреть как можно написать простейший веб-чат:

-3
-4

Сделаем так чтобы шаблон HTML находился в директории templates, код JS в отдельном файле и директории static, плюс консоль разработчика браузера постоянно ругается на отсутствующий файл favicon.ico, пропишем и его...

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

Первое что нужно сделать - вынести логику бэкенда, начнем с того что вынесем главный эндпойнт "/" в отдельный файл и подключим к нему шаблон файла index.html

Исходя из этого файла, далее нужны будут директория templates, в которой будет лежать файл index.html
Исходя из этого файла, далее нужны будут директория templates, в которой будет лежать файл index.html
Глядя на содержимое этого файла, понимаю что теперь надо создать директорию static в которой будет favicon.ico и app.js
Глядя на содержимое этого файла, понимаю что теперь надо создать директорию static в которой будет favicon.ico и app.js
Файл js как бы говорит - логику создания вебсокета нужно так же вынести в отдельный файл... например в ws_route.py
Файл js как бы говорит - логику создания вебсокета нужно так же вынести в отдельный файл... например в ws_route.py
-9

Осталось только оформить main.py в котором будут объединены роуты и подключена статика:

-10

Запускаю приложение: uvicorn main:app --port 8000 --reload и смотрю чтобы простенький веб-чат так же продолжал работать:

-11
-12

Приведенный выше пример, это лишь демонстрация работы вебсокетов.

Расширяем функционал

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

Простенький HTML для регистрации пользователя. При нажатии на кнопку "Войти в чат" будет происходить переадресация на эндпойнт /join_chat
Простенький HTML для регистрации пользователя. При нажатии на кнопку "Войти в чат" будет происходить переадресация на эндпойнт /join_chat

В эндпойнте /join_chat будет происходить извлечение введенных данных из формы и генерация user_id, после чего эти данные будут переданы в качестве контекста к файлу chat.html

-14
-15

Откуда происходит отправка данных (скрытый элемент для хранения данных комнаты) в файл JavaScript, где из них формируется экземпляр вебсокета:

-16

Последняя, 7я строчка скрипта отправляет нас на бэкенд, где и происходит обработка событий для вебсокета, с перечисленными параметрами (roomId, username, userId):

-17

Все сообщения (чтение и отправка) формируются в том же JS-скрипте что и создание экземпляра вебсокета:

-18

Результат работы в браузере:

-19

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

Создадим "Менеджер подключений" для вебсокетов:

-20

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

-21

Затем, нужно исправить app.js который обрабатывает входящие и исходящие сообщения чата:

-22

Так же отправку сообщения по "Enter" и оповещение других пользователей когда кто-то входит или выходит из чата:

-23

И вот как это работает в трех разных окнах:

-24

Вот теперь это уже больше походит на настоящий чат. Но всё равно, пока рано назвать его чатом в полном смысле. Нужно подключить какие нибудь стили. Изобретать тут особо не чего, я воспользуюсь готовым шаблоном от cdn.tailwindcss. Вставляемым скриптом между тегами <head> <script src="https://cdn.tailwindcss.com"></script> </head>

Остается только настроить стилизацию в нужных тегах, с помощью class и готовый chat.html выглядит так:

-25

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

-26

Ну и по аналогии, с главной страницей чата, исправлю шаблон регистрации пользователей register.html, чтобы регистрация в едином стиле с чатом:

-27

После добавления стилизации регистрация тоже стала выглядеть должным образом:

-28

Да, а что при входе пользователей происходит в консоли бэкенда?!

-29

Ну и как вишенка на торте - добавить стилизацию сообщений, чтобы отделить свои сообщения от сообщения других пользователей. Подправим обработчик входящих сообщений в app.js:

-30

И теперь, если сообщение написал я - одним цветом, другие пользователи - другим:

-31

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

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

Так что всем удачи в изучении чего бы то ни было!

Слава Богу!