https://github.com/pgibler/videochat
WebRTC client and server using Go + SolidJS
https://github.com/pgibler/videochat
coturn go golang redis solidjs webrtc
Last synced: about 2 months ago
JSON representation
WebRTC client and server using Go + SolidJS
- Host: GitHub
- URL: https://github.com/pgibler/videochat
- Owner: pgibler
- Created: 2025-12-10T21:19:24.000Z (6 months ago)
- Default Branch: main
- Last Pushed: 2025-12-16T06:06:21.000Z (6 months ago)
- Last Synced: 2025-12-16T11:04:22.437Z (6 months ago)
- Topics: coturn, go, golang, redis, solidjs, webrtc
- Language: TypeScript
- Homepage: https://videochat.vc
- Size: 122 KB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# videochat
A WebRTC application built with a Go signaling server and a SolidJS single-page app. Uses Redis to track connected peers and who is currently broadcasting.
## Stack
- Go HTTP/WebSocket server (Gorilla WebSocket)
- Redis for lightweight presence state
- SolidJS + Vite frontend
- Optional TURN relay (coturn) for fallback when STUN/host fails
## Prerequisites
- Go 1.21+ (tested with recent Go releases)
- Bun for the frontend build
- Redis running and reachable (defaults to `localhost:6379`)
## Quick Start
```bash
# 1) Install frontend deps
cd frontend
npm install # or bun install
# 2) Build the frontend assets
npm run build # emits dist/ consumed by the Go server
# 3) Run Redis (if not already running)
redis-server &
# 4) Start the Go backend (serves the built frontend and /ws)
cd ../backend
go run main.go
```
Then open http://localhost:8080 in multiple tabs to see peers join and start/stop broadcasting.
## Rooms
- Rooms are private and created on demand. Use the landing page “Create private room” button or `POST /api/rooms` to get a `{code, url}`.
- Share the room URL (e.g., `/rooms/{code}`) so peers can join and enter a display name.
- WebSocket connections must include the room code (`/ws?room={code}`); presence and broadcasts are isolated per room using Redis.
## Configuration
Environment variables (optional):
- `ADDR` - HTTP listen address (default `:8080`)
- `REDIS_ADDR` - Redis address (default `localhost:6379`)
- `STATIC_DIR` - Path to the frontend `dist/` (default `../frontend/dist`)
- `WS_PUBLIC_URL` - Optional; explicit WebSocket URL to advertise to clients (defaults to request host/proto and `/ws`)
- `STUN_URLS` - Comma-separated STUN URLs (default `stun:stun.l.google.com:19302`)
- `TURN_URLS` - Comma-separated TURN URLs (e.g., `turn:TURN_HOST:3478?transport=udp,turn:TURN_HOST:3478?transport=tcp`)
- `TURN_USERNAME` / `TURN_PASSWORD` - Credentials for TURN servers (if required)
- `ICE_MODE` - Optional; `stun-turn` (default) keeps both STUN+TURN, `turn-only` drops STUN and forces relay, `stun-only` skips TURN.
`.env` files are loaded from the project root, `backend/.env`, or `../.env`.
Copy `.env.example` to `.env` and adjust TURN host/credentials to match your coturn config.
Debug ICE config at runtime with `curl http://localhost:8080/debug/ice` (shows servers and mode).
Client settings (WebSocket URL, ICE mode/servers) are available at `GET /api/settings`; the WS URL defaults to the incoming request host unless `WS_PUBLIC_URL` is set.
## Development
- Frontend: `npm run dev -- --host` from `frontend/` for hot reload; the app reads the signaling URL from `/api/settings` (set `WS_PUBLIC_URL` on the backend if the public host differs).
- Backend: `go run main.go` from `backend/`. The server resets Redis presence sets on startup to avoid stale peer lists after restarts.
## TURN (coturn)
- Coturn config lives in `coturn/`. Copy `coturn/turnserver.conf.example` to `coturn/turnserver.conf` and adjust `realm`, `external-ip`, ports, and credentials.
- Start coturn:
- Native: `turnserver -c coturn/turnserver.conf` (stop via service manager or `pkill turnserver`).
- Docker: `cd coturn && ./run-docker.sh` (stop with `./stop-docker.sh`, container name defaults to `webrtc-coturn`).
- Ensure TURN creds match `TURN_USERNAME` / `TURN_PASSWORD` envs. When TURN is configured, the backend passes both STUN and TURN entries to the frontend via the WebSocket welcome message; ICE will try host/STUN first and fall back to TURN.
- Deployment runbook and pricing analysis live in `docs/TURN_DEPLOYMENT_GUIDE.md` and `docs/TURN_HOSTING_PRICE_ANALYSIS.md`.