Skip to content

Latest commit

 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

RealTime Call System

Discord-style group video/audio calls for 2–8 participants. WebRTC mesh topology, JWT auth, Next.js 14 + Node.js + Socket.IO.

Prerequisites

  • Node.js 20+
  • npm 9+

Setup

1. Install dependencies

npm install
cd backend && npm install
cd ../frontend && npm install
cd ..

2. Configure the backend

cp backend/.env.example backend/.env

Edit backend/.env:

PORT=4000
DATABASE_URL="file:./dev.db"
JWT_SECRET=<generate below>
FRONTEND_ORIGIN=http://localhost:3000

Generate a secret (run one of these):

# Linux/macOS
openssl rand -hex 32

# Windows PowerShell
[System.Convert]::ToBase64String([System.Security.Cryptography.RandomNumberGenerator]::GetBytes(32))

3. Configure the frontend

cp frontend/.env.local.example frontend/.env.local

The defaults work for local dev — no changes needed unless your backend is on a different port.

4. Initialize the database

npm run db:push --prefix backend

5. Start both servers

npm run dev

Backend → http://localhost:4000 | Frontend → http://localhost:3000


5-Step Manual Test Plan

  1. Open http://localhost:3000 in Window A. Click Register, create alice@example.com / password123.
  2. Type room ID test-room and click Join / Create Room.
  3. Open http://localhost:3000 in Window B (incognito or different browser). Register bob@example.com / password123.
  4. Type the same room ID test-room and join.
  5. Both windows show each other's video and hear audio within ~2 seconds. Toggle mic/cam — changes appear on the other side immediately. Click 📴 to leave.

Controls inside a call

Button Action
🎙 / 🔇 Toggle microphone — state propagates to all peers
📹 / 📷 Toggle camera — state propagates to all peers
📴 Leave the room

Known Limitations

STUN only — calls may fail behind symmetric NAT. Uses Google's public STUN (stun:stun.l.google.com:19302). For cross-network calls (not same LAN/localhost), add a TURN server: Coturn or Twilio NTS. Add TURN credentials to frontend/src/lib/webrtc.ts.

HTTPS required for camera/microphone outside localhost. getUserMedia only works on localhost without HTTPS. For any production deployment, serve the frontend over HTTPS.

Max 8 participants per room. Mesh topology: each user connects directly to every other user. Beyond 8, an SFU (mediasoup, LiveKit) would be needed.

JWTs expire after 7 days — no refresh tokens in v1.


File Structure

realtime-call-system/
├── backend/
│   ├── prisma/schema.prisma          # SQLite User model
│   ├── src/
│   │   ├── index.ts                  # HTTP + Socket.IO server boot
│   │   ├── env.ts                    # zod-validated env
│   │   ├── db.ts                     # Prisma client singleton
│   │   ├── auth/
│   │   │   ├── routes.ts             # POST /auth/register, /auth/login, GET /auth/me
│   │   │   ├── jwt.ts                # sign + verify JWT
│   │   │   └── middleware.ts         # requireAuth Express middleware
│   │   └── rtc/
│   │       ├── gateway.ts            # Socket.IO /rtc namespace + all event handlers
│   │       ├── rooms.ts              # in-memory room map + helpers
│   │       └── events.ts             # event name constants
│   ├── .env.example
│   ├── package.json
│   └── tsconfig.json
├── frontend/
│   ├── src/
│   │   ├── app/
│   │   │   ├── layout.tsx
│   │   │   ├── page.tsx              # redirects to /login or /rooms
│   │   │   ├── globals.css
│   │   │   ├── login/page.tsx
│   │   │   ├── register/page.tsx
│   │   │   └── rooms/
│   │   │       ├── page.tsx          # room id input
│   │   │       └── [roomId]/page.tsx # call screen + useCall logic
│   │   ├── lib/
│   │   │   ├── api.ts                # fetch wrapper with JWT header
│   │   │   ├── socket.ts             # socket.io-client singleton
│   │   │   └── webrtc.ts             # PeerManager class
│   │   ├── stores/
│   │   │   ├── authStore.ts          # zustand: user, token, login, logout
│   │   │   └── callStore.ts          # zustand: peers, streams, mute states
│   │   └── components/
│   │       ├── VideoTile.tsx
│   │       ├── CallGrid.tsx
│   │       └── CallControls.tsx
│   ├── .env.local.example
│   ├── package.json
│   ├── tsconfig.json
│   ├── tailwind.config.ts
│   └── next.config.mjs
├── .gitignore
├── package.json                      # root: runs both via concurrently
└── README.md

About

Discord-style group video/audio calls (2–8 participants) built with Next.js 14, Node.js, Socket.IO, and WebRTC mesh topology, with JWT auth.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages