Когда в октябре 2024-го заблокировали Дискорд, я сидел в голосовом канале с друзьями. Связь оборвалась, все полезли за впн-ками, кто-то ушёл в Телеграм, кто-то просто пропал. Серверы, которые мы строили годами, с каналами, ролями, ботами, в один момент стали недоступны.
Я фрилансер, пишу на React и Node.js. В тот вечер подумал: а насколько сложно вообще сделать свой мессенджер с серверной структурой? Не чат на вебсокетах из туториала, а нормальный. С серверами, каналами, ролями, голосовыми комнатами, ботами. Такой, чтобы можно было перетащить своё сообщество и не чувствовать разницы.
Оказалось, сложно. Но я всё равно сделал.
Что получилось
Проект называется Vela (с латыни «парус»). Это десктопное приложение на Электроне и веб-версия. Вот что работает прямо сейчас:
-
Серверы и каналы. Создаёшь сервер, внутри текстовые и голосовые каналы, категории. Всё как привычно.
-
Голосовые каналы. Заходишь и разговариваешь. Видео, демонстрация экрана, управление громкостью каждого участника. Под капотом WebRTC и Opus.
-
Роли и разрешения. 12 настраиваемых прав. Можно выдать роль «Модератор» с правом удалять сообщения, но без доступа к настройкам сервера. Разрешения работают и на уровне отдельных каналов.
-
Боты. Полноценный API: токены, вебхуки, слэш-команды с автодополнением, интерактивные кнопки, колбэки. Если писали ботов для Телеграма, разберётесь быстро, принцип похожий.
-
Личные сообщения. Отдельно от серверов. Файлы, реакции, стикеры, поиск по переписке.
-
Двухфакторная аутентификация, экспорт данных, удаление аккаунта. Всё что требует 152-ФЗ.
Серверы физически находятся в России. Работает без впн.
Стек
Тут будет скучно, но для Хабра в самый раз.
Клиент: React 18, TypeScript, Tailwind CSS, Framer Motion, Vite. Десктоп на Электроне с песочницей, изоляцией контекста и безопасным хранилищем для токенов (DPAPI на Виндоус, Keychain на Маке). Виртуализация сообщений через react-virtual, без неё при 10 000 сообщений в канале всё умирало.
Сервер: Node.js, Express, Prisma, PostgreSQL, Redis. Вебсокеты на ws, не Socket.io, чтобы контролировать протокол. Файлы льются в S3-совместимое хранилище (TWC Storage, серверы в России).
Голос: WebRTC, peer-to-peer. Кодек Opus 48 кГц. Web Audio API для микширования, шумоподавления и анализа громкости. Самая болезненная часть проекта, об этом ниже.
Инфраструктура: один на Aéza (Россия), PM2, Nginx, Let's Encrypt. Бэкапы базы каждую ночь. Мониторинг через свой эндпоинт /health + Яндекс Метрика на лендинге.
Что было больнее всего
Голосовые каналы
Думал, будет просто. Взял WebRTC, написал сигналинг, и готово. Нет.
Первая проблема: NAT traversal. В России у многих пользователей двойной NAT (оператор + роутер). STUN-сервер помогает не всегда, нужен TURN для ретрансляции. А TURN это трафик через мой сервер, и он стоит денег.
Вторая: обратная связь от микрофона. Без эхоподавления голос возвращается с задержкой 200мс и начинается ад. Пришлось ковырять Web Audio API: анализатор громкости, voice activity detection, автоматическое отключение микрофона при тишине.
Третья: утечки памяти. MediaStream и AudioContext не отпускают ресурсы если их не закрыть вручную. После часа звонка приложение начинало тормозить. Пока не расставил disconnectSource() и close() в нужных местах, было больно.
Вебсокеты и реконнект
Казалось бы: клиент подключается, сервер шлёт события. Но нет.
Что если у пользователя пропал вайфай на 3 секунды? Сообщения, отправленные за это время, просто теряются. Пришлось делать: экспоненциальный бэкофф при реконнекте (от 1 до 30 секунд с джиттером), хартбит каждые 30 секунд с таймаутом на понг, и гэп-филл после переподключения, когда клиент запрашивает пропущенные сообщения.
Звучит очевидно, но каждый из этих пунктов это баги, которые я ловил в продакшене неделями.
Безопасность
Когда делаешь мессенджер, безопасность не «потом допилим». Я провёл полный аудит: от XSS (нашёл, что маркдаун-рендерер не санитизировал HTML, привет DOMPurify) до привилегий в ролевой системе (роль с правом «управление ролями» могла назначить себе все права, классический privilege escalation).
Полный список того, что пришлось закрыть:
-
Шифрование токена через системное хранилище (а не JSON-файл на диске)
-
Проверка origin при подключении к вебсокетам
-
Тайминг-безопасное сравнение TOTP-кодов
-
Блокировка аккаунта после 5 неудачных попыток входа
-
Rate limiting на все мутационные эндпоинты
-
Content Security Policy, HSTS, безопасные куки
Размер проекта
Чтобы понять масштаб, вот цифры на сегодня:
-
Около 300 компонентов на клиенте
-
50+ API-маршрутов на сервере
-
20+ таблиц в Prisma-схеме
-
51 API-тест, 5 E2E-тестов
-
14 ErrorBoundary (после аудита было 6)
-
Сборка: ~800 КБ основной бандл (разбит на чанки), установщик ~93 МБ
Это не стартап с командой из десяти человек. Это один человек с ноутбуком и Claude Code в терминале. Да, я активно использую ИИ-ассистенты для кодинга и не стесняюсь этого. Но каждое архитектурное решение, каждый компромисс, каждый баг в три часа ночи, всё это моё.
Зачем это всё
Честный ответ: я не планировал «убить Дискорд». Я хотел сделать инструмент, которым сам бы пользовался. Мессенджер с серверной структурой, который работает в России без костылей.
Сейчас на рынке есть альтернативы: Lenza Arena (115 тысяч пользователей, но лимит 15 человек в голосовом канале), Revolt (меж��ународный, на бета-стадии, серверы за границей), корпоративные решения вроде VK Teams и SaluteJazz (не для сообществ). Полноценного российского аналога с серверами, каналами, ролями, ботами и голосовыми комнатами я не нашёл. Поэтому сделал.
Что дальше
Я выпустил Vela в открытый доступ. Прямо сейчас можно:
-
Скачать приложение для Windows: velachat.ru
-
Открыть в браузере без установки velachat.online
-
Создать свой сервер и позвать друзей
Мне интересна обратная связь. Не абстрактная «ну, прикольно», а конкретная: что сломалось, чего не хватает, что раздражает. Я один, и мне важно понять, куда вкладывать следующие 200 часов разработки.
В ближайших планах:
-
Версия для macOS и Linux (сборки настроены, нужно тестирование)
-
Мобильное приложение (это отдельная большая история)
-
Рассматриваю возможность открыть исходный код
Если зайдёте, попробуете и напишете мне, буду благодарен. На официальном сервере Vela есть каналы для обратной связи и баг-репортов.
Я Денис, фрилансер из Нижнего Новгорода. Занимаюсь веб-разработкой, Телеграм-ботами и иногда мессенджерами. Сайт проекта: velachat.ru и веб приложение velachat.online
Автор: Mhessel
