WebRTC комнаты в ezgu.games: почему LiveKit, а не Zoom
Зачем нам собственная WebRTC-инфраструктура
Когда мы запускали онлайн-комнаты в ezgu.games, очевидное решение было — использовать Zoom или Google Meet через ссылку. Игроки заходят в Meet, параллельно открывают Mini App, играют. Технически — работает.
Через две недели тестирования стало ясно, что это плохой UX: вы открываете два окна, в одном видите карты, в другом — лица. Карта говорит «следующий — Артём», но Zoom не подсвечивает Артёма, и вы переключаетесь между окнами, чтобы найти, кто это. Удержание в первой сессии падало на 40% именно из-за этой раздробленности.
Решение — встроить видеосвязь прямо в Mini App. Когда карта говорит «следующий — Артём», лицо Артёма в видеосетке подсвечивается автоматически. Когда он отвечает, его карта остаётся в фокусе. Один экран, всё на месте.
Почему LiveKit, а не Twilio или Agora
LiveKit — open-source платформа для WebRTC, базируется на Pion (Go-библиотека для WebRTC). Альтернативы: Twilio Programmable Video, Agora.io, Daily.co.
Мы выбрали LiveKit по трём причинам:
1. Self-hosting. Twilio и Agora — managed services с фиксированной ценой за минуту. На 1000 минут видео в день это становится дорого. LiveKit можно развернуть на своей VM и платить только за инфраструктуру.
2. Стоимость. Tw/Ag = 0,004–0,01 USD за минуту видео × количество участников. Для комнаты на 6 человек на 30 минут — это 0,72–1,8 USD. LiveKit на нашей одной GCE VM (e2-standard-4) выдерживает 10 параллельных комнат при 6 участниках = 0,15 USD/час железо, делите на много партий.
3. SFU архитектура. LiveKit использует Selective Forwarding Unit (одна сторона передаёт видео-стрим, сервер раздаёт остальным). Это значит, что нагрузка на клиент меньше, чем в классической P2P-схеме при 4+ участниках. На 6 участниках мобильная сеть уже захлёбывается без SFU.
Архитектура комнат
Когда юзер создаёт комнату:
- Mini App отправляет POST /api/rooms на наш Express API.
- API создаёт row в Postgres (Room в Prisma), пишет lobby state.
- API запрашивает у LiveKit-сервера access token для комнаты.
- Mini App открывает WebSocket к Socket.IO + WebRTC к LiveKit.
Мы используем два разных канала специально:
- Socket.IO — для game state (whose turn, current card, chat messages).
- LiveKit — для media (audio, video).
Если LiveKit упал или клиент заблокировал камеру — игра продолжает работать, просто без видео. Это критично, потому что в реальности у части пользователей корпоративные сети режут WebRTC, и мы не хотим их выкидывать из игры.
Per-turn чат
Внутри игровой комнаты мы добавили чат, привязанный к ходам — Per-turn chat. Каждый ход (Turn) имеет свой набор сообщений. Когда ход заканчивается, сообщения остаются в БД, но в UI исчезают (пользователь видит только текущий ход).
Зачем такая структура — два причины:
1. Анализ контента карт. Сообщения чата — ценный сигнал «карта вытянула содержательный ответ или провалилась в тишину». Мы можем анализировать, какие карты в каком контексте лучше работают.
2. UX. В партии на 30 минут чат накапливает сотни сообщений. Если показывать всё подряд, новые игроки тонут в истории. Per-turn структура держит фокус.
Безопасность и модерация
WebRTC — это прямой канал между пользователями, и в нём могут происходить любые непотребства. Защита в три слоя:
Слой 1 — голос. Если пользователь использует голосовой канал и говорит что-то неуместное — у каждого участника есть кнопка «пожаловаться», которая мьютит его и отправляет жалобу в модерацию.
Слой 2 — чат-фильтр. Текстовый чат проходит через AI-фильтр на оскорбления, угрозы, личные данные. Подозрительные сообщения требуют подтверждения от автора.
Слой 3 — rate limit. Не больше 10 сообщений в минуту от одного человека, не больше 50 в минуту в комнате. Защита от флуда.
За 6 месяцев работы:
- 14 000 комнат создано.
- 73 жалобы на модерацию (0,5% от всех комнат).
- 18 случаев бана (0,1%).
- 0 серьёзных инцидентов с приватными данными.
Что дальше
- Recording (по согласию). Возможность записать сессию для тех, кто хочет пересматривать. Только с явным согласием всех участников.
- Screenshare для команд. В колоде «Для команд» — возможность шарить экран (кода, документа), чтобы обсуждать его в формате игры.
- Live Translate. Если в комнате участники разных языков — субтитры в реальном времени через Whisper + DeepL.
Попробовать
Создайте комнату через @EzguGamesCorpBot в Telegram. Поделитесь ссылкой с друзьями. До 8 человек в одной комнате, бесплатно.
Мы в соц сетях
Подписывайся, чтобы не пропустить новые колоды и реальные тусовки.