Skip to content

bb-hackathon/tcp-chat

Repository files navigation

Кейс 3. TCP чат-сервер и клиент

Important

Команда Бадибилдинг (участники и роли в команде)

  • mxxntype (Капитан) - Rust-сервер, контейнеризация, шифрование и безопасность серверной архитектуры
  • ddlifter - Go-клиент, фронтенд, тестирование, CI-процесс
  • Sharker5854 - Фронтенд, тестирование, Redis, проектирование БД, шифрование и безопасность транспортного уровня
  • KlausReinherz - Фронтенд, дизайн, тестирование, модель машинного обучения
  • ZarevskyMan - Фронтенд, дизайн, тестирование

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

1. Фронтенд-разработка:

  • Создание современного веб-интерфейса, который предоставляет пользователям интуитивно понятный и визуально привлекательный способ взаимодействия с основными функциями приложения;
  • Разработка адаптивного дизайна, который корректно отображается на различных устройствах и платформах;
  • Интеграция динамических элементов интерфейса, таких как интерактивные формы, анимации и переходы, для обеспечения высокого уровня вовлеченности пользователей.

2. Применение машинного обучения:

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

3. Разработка протокола коммуникации:

  • Определение и реализация простого протокола на основе TCP для обмена сообщениями между клиентом и сервером. Протокол должен поддерживать отправку и получение текстовых сообщений, а также управляющие команды (например, для авторизации или выхода из чата).

4. Сервер:

  • Реализация серверной части, способной принимать подключения от множества клиентов одновременно;
  • Сервер должен поддерживать рассылку сообщений от одного клиента всем остальным подключенным клиентам;
  • Обработка подключений и сообщений должна осуществляться асинхронно или в многопоточном режиме для обеспечения масштабируемости и отзывчивости.

5. Клиент:

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

6. Управление соединениями:

  • Разработка механизмов для корректного управления подключениями, включая обработку разрывов соединения и корректное закрытие сессий как на стороне сервера, так и на стороне клиента.

7. Безопасность и аутентификация:

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

Дополнительные задачи (по желанию):

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

Реализованные технологии и функционал

Чат реализован с использованием микросервисной архитектуры (см. "Архитектура"), и состоит из 6 основных контейнеризованных сервисов.

На стороне сервера

  • Сервер на Rust
  • Реляционная база данных PostgreSQL
  • key-value кэш / база данных Redis
  • Локальная модель машинного обучения Ollama

На стороне клиента

  • Клиент на Go
  • Веб-фронтенд (Классический HTML + CSS + JS)

Основная коммуникация происходит между Rust-сервером и Go-клиентом. Они общаются с помощью протокола TCP, и использованием формата обмена данными Protobuf (gRPC). На траспортном уровне применяется TLS-шифрование.

Протокол

Как было сказано ранее, общение между сервером и клиентом происходит по TCP-каналу, формат обмена сообщениями - protocol buffers (Protobuf), c использованием RPC-фрейморка gRPC.

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

  1. Скорость и надежность обмена данными: Protobuf - современный и эффективный протокол сериализации данных, предлагающий максимальную производительность и надежность передачи данных.

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

  3. Модульность и гибкость: gRPC предоставляет поддержку для балансировки нагрузки, трассировки, проверки состояния и аутентификации. Это упрощает настройку и управление высокопроизводительными системами. В рамках нашего проекта, эти способности были в полной мере использованы для построения надежной системы аутентификации запросов и полноценной системы логирования.

  4. Генерация кода: gRPC предлагает встроенные возможности генерации кода для клиента и сервера во множестве языков, благодаря компилятору Protocol Buffers (protoc). Это упрощает разработку API. В нашем проекте, на стороне сервера генерацией кода занимается tonic для Rust и сам protoc для Go.

Функционал чата

В чате предусмотрена возможность создания защищенного аккаунта, отправка текстовых сообщений другим пользователям, а так же создание чат-комнат с несколькими пользователями. Все данные хранятся в базе данных и надежно защищены (см. "Безопасность"). Обмен сообщениями и прочими событиями происходит в реальном времени с использованием потоковой передачи gRPC.

Особенности сервера

Сервер написан на Rust и асинхронно обрабатывает любое количество одновременных подключений от клиентов. Внутри сервера реализованно несколько различных типов каналов (tokio::mpsc - Multi-producer, single consumer, tokio::broadcast, tokio::oneshot), используемых для эффективной передачи данных между асинхронными задачами, а так же собственноручно реализованный канал DisconnectChannel, предлагающий возможность обнаружения разрывов соединений и плавного завершения работы соответствующих задач.

Основные библиотеки

  • tokio - Управляемая событиями неблокирующая IO-платформа для написания асинхронных приложений.
  • tonic - Rust-реализация gRPC, высокопроизводительного RPC-фреймворка с открытым исходным кодом.
  • diesel - ORM и конструктор запросов, разработанный для упрощения взаимодействия с базами данных.
  • redis - Rust-реализация клиентской библиотеки Redis.
  • tracing - Фреймворк для инструментирования программ Rust для сбора структурированной диагностической информации, основанной на событиях.
  • uuid - UUID, уникальное 128-разрядное значение, хранящееся в виде 16 октетов и обычно форматируемое как шестнадцатеричная строка в пяти группах.
  • streebog - Реализация криптографической хэш-функции Streebog, определенной в ГОСТ Р 34.11-2012.
  • rand_chacha - Криптографически защищенный генератор случайных чисел, использующий алгоритм ChaCha20.

Безопасность

При обмене данных между сервером и клиентом применяется шифрование на траспортном уровне (TLS/SSL), пароли в базе данных хранятся в хэшированном виде (алгоритм хэширования - ГОСТ 34.11-2012 "Стрибог"), для первичных ключей используется UUID версии 4, а аутентификационные токены генерируются с помощью криптографически защищенного алгоритма ChaCha20.

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

Модель машинного обучения

В проекте используется локальная ИИ-модель, развернутая с помощью сервиса Ollama. Модель способна анализировать сообщения в чат-комнате (или приватном чате) и предлагать дополнительную информацию по теме чата, а так же предоставлять рекомендации по улучшению пользовательского опыта в реальном времени. На сервере реализован весь функционал, чтобы с помощью LLM можно было, например, анализировать логи, выявлять подозрительных пользователей и дополнять комнаты интересной информацией.

Быстродействие и надежность

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

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

Клиент

Клиент реализован на Go, и представляет собой гибрид gRPC-клиента (для общения с Rust-сервером) и RESTful сервера (для общения с фронтендом). Использование Go позволяет снять вычислительную нагрузку с фронтенда, а так же более безопасно и эффективно реализовать общение с сервером. Так же, такой подход отделяет реализацию протокола от реализации ползовательского интерфейса, что в дальнейшем упростит разработку других фронтендов.

Фронтенд

Фронтенд реализован на классической связке HTML + CSS + JS, и представляет собой красивый, простой и минималистичный интерфейс для отправки сообщений в наше чат-приложение. Предоставляется возможность регистрации и логина, создания комнат и отправки сообщений. Сообщения от других пользователей приходят в реальном времени.

Архитектура

Архитектура

Асинхронная диаграмма сервера (In progress)

Асинхронная диаграмма сервера

Локальная сборка и развертывание серверной части

С помощью Docker

Tip

Это наиболее разумный способ развертывания. Остальные приведены для справки.

# Собрать только контейнер с сервером.
cd server && docker build . -t tcp-chat

# Поднять всю серверную часть. (БД, прогон конверсий, сервер, pgAdmin)
docker compose up --detach --build

# Просмотр логов.
docker compose logs --follow
docker compose logs <service> --follow # Логи конкретного сервиса.

# Shutdown серверной части.
docker compose down

Без контейнеризации

Установить cargo - официальную систему сборки Rust через rustup.

curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh # Установка Rust.

cargo build --release # Сборка сервера.
cargo run --release   # Запуск сервера.
cargo clippy          # Линтер.

Important

В системе необходим protoc

С помощью Nix

nix build . # Ага, вот так просто.