Минимальный self-hosted голосовой чат с приватными комнатами и передачей звука через WebRTC.
Проект обеспечивает лёгкую и быструю голосовую связь прямо в браузере. Комнаты создаются по запросу, доступны только по ID/ссылке, а голос передаётся через WebRTC без сторонних сервисов.
-
🔒 Приватные комнаты
Создание комнаты, подключение по ID, выход из комнаты. -
🎤 Голос через WebRTC
Автоматическая передача голоса после подключения. Браузер обеспечивает echo cancellation, noise suppression и AGC. -
🔊 Управление звуком
Включение/выключение микрофона и входящего звука. -
🔁 Автопереподключение WebRTC
Клиент восстанавливает голосовой поток после разрыва. -
📡 Постоянное WebSocket‑соединение
Используется для управления комнатами и WebRTC‑сигналинга. -
👥 События комнаты
Обновления участников: вход, выход, обновление имени. -
⚠️ Ограничение частоты создания комнат
Сервер возвращает{"type": "error", "error": "rate_limited"}при превышении лимитов.
go run ./cmd/server/main.goПо умолчанию сервер раздаёт статические файлы и поднимает WebSocket‑сигналинг по адресу:
/api/ws/signal
Перейдите в браузере на:
http://localhost:8080/
- Нажмите Create Room — получите ID комнаты.
- Отправьте ссылку другому участнику.
- После присоединения голос начинает передаваться автоматически.
- Можно:
- менять имя,
- включать/выключать микрофон,
- выключать входящий звук,
- переподключать WebRTC вручную.
Все события идут через /api/ws/signal.
{ "type": "create_room", "name": "optional" }
{ "type": "join", "room": "ROOM_ID", "name": "optional" }
{ "type": "leave" }
{ "type": "rename", "name": "New Name" }
{ "type": "offer", "sdp": "..." }
{ "type": "answer", "sdp": "..." }
{ "type": "candidate", "candidate": "...", "sdpMid": "0", "sdpMLineIndex": 0 }
{ "type": "whoami" }
{ "type": "ping" }{ "type": "room_created", "room": "ROOM_ID" }
{ "type": "room_state", "room": "ROOM_ID", "room_name": "...", "members": [...], "count": 1 }
{ "type": "member_joined", "user": {...} }
{ "type": "member_left", "user": {...} }
{ "type": "member_updated", "user": {...} }
{ "type": "answer", "sdp": "..." }
{ "type": "offer", "sdp": "..." }
{ "type": "candidate", "candidate": "..." }
{ "type": "pong" }
{ "type": "error", "error": "rate_limited" }- 🔊 Индикатор «кто говорит» (VAD через RTP extension)
- 🎥 Поддержка видеопотоков
- 📈 Статус WebRTC соединения (rtt/loss/jitter)
- 🔐 Авторизация пользователей
- 🧩 Улучшенный UI/UX
Проект распространяется под лицензией GNU AGPLv3