Skip to content

since-2017-hub/webRTC-call-backend

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

9 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

# Video Call Backend Server

A Node.js backend server for the video calling application, built with Express and Socket.io. This server handles user authentication, real-time signaling for WebRTC connections, and manages user presence.

## πŸš€ Features

- **Real-time Signaling** - WebRTC signaling server using Socket.io

- **User Management** - In-memory user storage and presence tracking

- **Call Management** - Handle call initiation, acceptance, rejection, and termination

- **Authentication API** - Simple REST API for user login

- **ICE Candidate Exchange** - Facilitate peer-to-peer connection establishment

- **Connection Health** - Ping/pong for connection monitoring

## πŸ“‹ Prerequisites

- **Node.js** (v16 or higher)

- **npm** or **yarn**

## πŸ› οΈ Installation

### 1. Navigate to Server Directory

cd server

### 2. Install Dependencies

npm install

### 3. Start the Server

\# Production

npm start



\# Development (with auto-restart)

npm run dev

The server will start on http://localhost:3001

## πŸ“¦ Dependencies

### Production Dependencies

{

  "express": "^4.18.2",      // Web framework

  "socket.io": "^4.7.2",     // WebSocket server

  "cors": "^2.8.5",          // Cross-origin requests

  "uuid": "^9.0.0"           // Unique ID generation

}

### Development Dependencies

{

  "nodemon": "^3.0.1"        // Auto-restart during development

}

## πŸ—οΈ Server Architecture


server/

β”œβ”€β”€ index.js              # Main server file

β”œβ”€β”€ package.json           # Dependencies and scripts

β”œβ”€β”€ package-lock.json      # Dependency lock file

└── README.md             # This file

## πŸ”Œ API Endpoints

### REST API

#### POST /api/login

Authenticate a user and return user data.

**Request:**

{

  "username": "john\_doe",

  "password": "any\_password"

}

**Response:**

{

  "user": {

    "id": "uuid-string",

    "username": "john\_doe",

    "isOnline": false

  },

  "token": "uuid-string"

}

**Error Response:**

{

  "error": "Username and password required"

}

#### GET /api/users

Get all users (online and offline).

**Response:**

\[

  {

    "id": "uuid-string",

    "username": "john\_doe",

    "isOnline": true

  }

]

#### GET /api/online-users

Get only online users.

**Response:**

\[

  {

    "id": "uuid-string",

    "username": "john\_doe",

    "isOnline": true,

    "socketId": "socket-id"

  }

]

## πŸ”„ Socket.io Events

### Client β†’ Server Events

#### join

User joins the server and goes online.

socket.emit('join', {

  id: 'user-uuid',

  username: 'john\_doe'

});

#### call\_user

Initiate a call to another user.

socket.emit('call\_user', {

  to: 'target-user-id',

  from: { id: 'caller-id', username: 'caller' },

  callType: 'video', // or 'audio'

  offer: rtcSessionDescription

});

#### accept\_call

Accept an incoming call.

socket.emit('accept\_call', {

  callId: 'call-uuid',

  answer: rtcSessionDescription

});

#### reject\_call

Reject an incoming call.

socket.emit('reject\_call', {

  callId: 'call-uuid'

});

#### end\_call

End an active call.

socket.emit('end\_call', {

  callId: 'call-uuid'

});

#### ice\_candidate

Exchange ICE candidates for WebRTC connection.

socket.emit('ice\_candidate', {

  to: 'target-user-id',

  candidate: rtcIceCandidate

});

#### ping

Health check ping.

socket.emit('ping');

### Server β†’ Client Events

#### join\_success

Confirmation of successful join.

{

  message: 'Successfully connected to the server',

  onlineUsers: \[/\* array of online users \*/]

}

#### users\_updated

Broadcast when user list changes.

\[/\* array of currently online users \*/]

#### incoming\_call

Notify user of incoming call.

{

  callId: 'call-uuid',

  from: { id: 'caller-id', username: 'caller' },

  callType: 'video',

  offer: rtcSessionDescription

}

#### call\_accepted

Notify caller that call was accepted.

{

  callId: 'call-uuid',

  answer: rtcSessionDescription

}

#### call\_rejected

Notify caller that call was rejected.

{

  callId: 'call-uuid'

}

#### call\_ended

Notify that call has ended.

{

  callId: 'call-uuid'

}

#### call\_status

Update on call status.

{

  status: 'ringing', // or 'user\_offline'

  callId: 'call-uuid'

}

#### ice\_candidate

Forward ICE candidate to peer.

{

  from: 'sender-user-id',

  candidate: rtcIceCandidate

}

#### pong

Response to ping.

// No data, just event

## πŸ’Ύ Data Storage

### In-Memory Storage

The server uses in-memory storage for demo purposes:

const users = new Map();        // All users (persistent)

const activeUsers = new Map();  // Currently online users

const calls = new Map();        // Active calls

### User Object Structure

{

  id: 'uuid-string',

  username: 'john\_doe',

  isOnline: true,

  socketId: 'socket-id',

  lastSeen: '2023-12-01T10:30:00.000Z'

}

### Call Object Structure

{

  id: 'call-uuid',

  from: { id: 'caller-id', username: 'caller' },

  to: { id: 'callee-id', username: 'callee' },

  callType: 'video',

  status: 'ringing',

  startTime: 1701423000000

}

## πŸ”§ Configuration

### Environment Variables

PORT=3001                    # Server port (default: 3001)

NODE\_ENV=development         # Environment mode

### CORS Configuration

const io = socketIo(server, {

  cors: {

    origin: "http://localhost:5173",  // Frontend URL

    methods: \["GET", "POST"]

  }

});

### Express Middleware

app.use(cors());                    // Enable CORS

app.use(express.json());            // Parse JSON bodies

## πŸ” Logging & Debugging

### Console Logs

The server provides detailed logging:

- πŸ”Œ Connection events

- πŸ‘₯ User join/leave events

- πŸ“ž Call state changes

- 🧊 ICE candidate exchanges

- ❌ Error conditions

### Debug Mode

Enable detailed logging:

DEBUG=socket.io\* npm start

## πŸš€ Deployment

### Local Development

npm run dev    # Uses nodemon for auto-restart

### Production Deployment

#### 1. **Heroku**

\# Create Procfile

echo "web: node index.js" > Procfile



\# Deploy

git add .

git commit -m "Deploy to Heroku"

git push heroku main

#### 2. **Railway**

\# railway.json

{

  "build": {

    "builder": "NIXPACKS"

  },

  "deploy": {

    "startCommand": "node index.js"

  }

}

#### 3. **DigitalOcean App Platform**

\# .do/app.yaml

name: video-call-server

services:

\- name: api

  source\_dir: /server

  github:

    repo: your-repo

    branch: main

  run\_command: node index.js

  environment\_slug: node-js

  instance\_count: 1

  instance\_size\_slug: basic-xxs

### Production Considerations

#### 1. **Environment Variables**

PORT=80

NODE\_ENV=production

CORS\_ORIGIN=https://your-frontend-domain.com

#### 2. **Process Management**

\# Using PM2

npm install -g pm2

pm2 start index.js --name "video-call-server"

pm2 startup

pm2 save

#### 3. **Reverse Proxy (Nginx)**

server {

    listen 80;

    server\_name your-domain.com;

    

    location / {

        proxy\_pass http://localhost:3001;

        proxy\_http\_version 1.1;

        proxy\_set\_header Upgrade $http\_upgrade;

        proxy\_set\_header Connection 'upgrade';

        proxy\_set\_header Host $host;

        proxy\_cache\_bypass $http\_upgrade;

    }

}

## πŸ›‘οΈ Security Considerations

### Current Limitations (Demo Only)

- **No real authentication** - accepts any username/password

- **In-memory storage** - data lost on restart

- **No rate limiting** - vulnerable to spam

- **No input validation** - accepts any data

- **No encryption** - messages sent in plain text

### Production Security Measures

// Rate limiting

const rateLimit = require('express-rate-limit');

app.use(rateLimit({

  windowMs: 15 \* 60 \* 1000, // 15 minutes

  max: 100 // limit each IP to 100 requests per windowMs

}));



// Input validation

const { body, validationResult } = require('express-validator');

app.post('/api/login', \[

  body('username').isLength({ min: 3 }).trim().escape(),

  body('password').isLength({ min: 6 })

], (req, res) => {

  const errors = validationResult(req);

  if (!errors.isEmpty()) {

    return res.status(400).json({ errors: errors.array() });

  }

  // ... rest of login logic

});



// Helmet for security headers

const helmet = require('helmet');

app.use(helmet());

## πŸ“Š Performance Monitoring

### Health Check Endpoint

app.get('/health', (req, res) => {

  res.json({

    status: 'OK',

    timestamp: new Date().toISOString(),

    uptime: process.uptime(),

    memory: process.memoryUsage(),

    activeUsers: activeUsers.size,

    activeCalls: calls.size

  });

});

### Metrics to Monitor

- **Active connections** - Number of connected users

- **Memory usage** - Server memory consumption

- **Call success rate** - Percentage of successful calls

- **Response time** - API endpoint response times

## πŸ› Troubleshooting

### Common Issues

#### 1. **Port Already in Use**

\# Find process using port 3001

lsof -i :3001



\# Kill the process

kill -9 <PID>

#### 2. **CORS Errors**

- Update CORS origin in server configuration

- Ensure frontend URL matches CORS settings

#### 3. **Socket Connection Failed**

- Check if server is running

- Verify firewall settings

- Ensure WebSocket support is enabled

#### 4. **Memory Leaks**

- Monitor memory usage with process.memoryUsage()

- Implement proper cleanup for disconnected users

- Clear inactive calls periodically

### Debug Commands

\# Check server status

curl http://localhost:3001/health



\# Test login endpoint

curl -X POST http://localhost:3001/api/login \\

&nbsp; -H "Content-Type: application/json" \\

&nbsp; -d '{"username":"test","password":"test"}'



\# Monitor logs

tail -f server.log

## πŸ”„ API Testing

### Using curl

\# Test login

curl -X POST http://localhost:3001/api/login \\

&nbsp; -H "Content-Type: application/json" \\

&nbsp; -d '{"username":"testuser","password":"testpass"}'



\# Get users

curl http://localhost:3001/api/users



\# Get online users

curl http://localhost:3001/api/online-users

### Using Postman

Import the following collection:

{

&nbsp; "info": { "name": "Video Call API" },

&nbsp; "item": \[

&nbsp;   {

&nbsp;     "name": "Login",

&nbsp;     "request": {

&nbsp;       "method": "POST",

&nbsp;       "url": "http://localhost:3001/api/login",

&nbsp;       "body": {

&nbsp;         "mode": "raw",

&nbsp;         "raw": "{\\"username\\":\\"test\\",\\"password\\":\\"test\\"}"

&nbsp;       }

&nbsp;     }

&nbsp;   }

&nbsp; ]

}

## πŸ“š Additional Resources

- [Socket.io Documentation](https://socket.io/docs/)

- [Express.js Guide](https://expressjs.com/en/guide/)

- [WebRTC Signaling](https://developer.mozilla.org/en-US/docs/Web/API/WebRTC\_API/Signaling\_and\_video\_calling)

- [Node.js Best Practices](https://github.com/goldbergyoni/nodebestpractices)


**Server ready for video calling! πŸš€**

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors