Files
chatrtc/server/README.md
2025-06-15 16:32:37 +02:00

7.6 KiB

ChatRTC Signaling Server

Advanced WebRTC signaling server built with Node.js and Socket.IO for the ChatRTC Android application.

Features

  • 🚀 Real-time WebRTC Signaling - Handle offer/answer/ICE candidate exchange
  • 🏠 Room Management - Support for multiple chat rooms
  • 👥 User Management - Track users, nicknames, and states
  • 💬 Message Fallback - Backup text messaging via Socket.IO
  • 📊 REST API - Monitor server status and room information
  • 🔒 Error Handling - Comprehensive error handling and logging
  • 📱 Mobile Optimized - Optimized for Android WebRTC connections
  • 🌐 CORS Support - Flexible cross-origin configuration
  • Performance - Built for high-performance real-time communication

Quick Start

1. Installation

cd server
npm install

2. Configuration

Copy the environment configuration:

cp .env.example .env

Edit .env file with your settings:

NODE_ENV=development
PORT=3000
HOST=0.0.0.0
ALLOWED_ORIGINS=*

3. Start the Server

Development mode:

npm run dev

Production mode:

npm start

With PM2 (recommended for production):

npm run pm2:start

4. Verify Installation

Open your browser and navigate to http://localhost:3000 to see the server status page.

API Endpoints

REST API

Endpoint Method Description
/ GET Server status page (HTML)
/api/status GET Server statistics (JSON)
/api/rooms GET List all active rooms
/api/rooms/:roomId GET Get specific room information
/health GET Health check endpoint

Example API Responses

GET /api/status

{
  "status": "running",
  "timestamp": "2025-06-15T10:30:00.000Z",
  "connectedUsers": 5,
  "activeRooms": 2,
  "uptime": 3600
}

GET /api/rooms

[
  {
    "roomId": "main-chat",
    "userCount": 3,
    "users": [
      {
        "nickname": "Alice",
        "joinedAt": "2025-06-15T10:25:00.000Z"
      },
      {
        "nickname": "Bob", 
        "joinedAt": "2025-06-15T10:28:00.000Z"
      }
    ]
  }
]

Socket.IO Events

Client → Server

Event Data Description
join-room {nickname, roomId?} Join a chat room
offer {targetSocketId?, offer} Send WebRTC offer
answer {targetSocketId, answer} Send WebRTC answer
ice-candidate {targetSocketId?, candidate} Send ICE candidate
media-state {isVideoEnabled, isAudioEnabled} Update media state
chat-message {message} Send text message (fallback)
get-rooms - Request room list
get-room-users - Request current room users
ping - Connection health check

Server → Client

Event Data Description
joined-room {roomId, nickname, users} Successful room join
user-joined {socketId, nickname, joinedAt} New user joined
user-left {socketId, nickname, reason} User disconnected
offer {fromSocketId, fromNickname, offer} Received WebRTC offer
answer {fromSocketId, fromNickname, answer} Received WebRTC answer
ice-candidate {fromSocketId, fromNickname, candidate} Received ICE candidate
user-media-state {socketId, nickname, isVideoEnabled, isAudioEnabled} User media state changed
chat-message {fromSocketId, fromNickname, message, timestamp} Received text message
rooms-list [{roomId, userCount, users}] Available rooms
room-users {roomId, users} Current room users
error {message, code?} Error occurred
pong {timestamp} Ping response

Android Integration

Update WebRTCManager.java

Replace the signaling server URL in your Android app:

// In WebRTCManager.java
private static final String SIGNALING_SERVER_URL = "http://YOUR_SERVER_IP:3000";

// For local development with Android emulator:
private static final String SIGNALING_SERVER_URL = "http://10.0.2.2:3000";

// For real device on same network:
private static final String SIGNALING_SERVER_URL = "http://192.168.1.XXX:3000";

Socket.IO Connection Example

// Connect to server
socket = IO.socket(SIGNALING_SERVER_URL);

// Join room
JsonObject joinData = new JsonObject();
joinData.addProperty("nickname", nickname);
joinData.addProperty("roomId", "main-chat"); // optional
socket.emit("join-room", joinData);

// Handle room joined
socket.on("joined-room", args -> {
    JsonObject data = gson.fromJson(args[0].toString(), JsonObject.class);
    String roomId = data.get("roomId").getAsString();
    // Handle successful join
});

Production Deployment

1. Environment Setup

# Create production environment file
cp .env.example .env

# Edit for production
nano .env

Set production values:

NODE_ENV=production
PORT=3000
HOST=0.0.0.0
ALLOWED_ORIGINS=https://yourdomain.com

For production, use HTTPS. You can:

  • Use a reverse proxy (nginx, Apache)
  • Configure SSL directly in the server
  • Use a load balancer with SSL termination

3. Process Management

Using PM2:

npm install -g pm2
npm run pm2:start

# Monitor
pm2 status
pm2 logs chatrtc-server
pm2 monit

Using Docker:

FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm install --production
COPY . .
EXPOSE 3000
CMD ["npm", "start"]

4. Performance Optimization

  • Enable gzip compression (included)
  • Use clustering for multiple CPU cores
  • Configure proper logging levels
  • Set up monitoring and alerting
  • Use Redis for scaling (future enhancement)

Monitoring

Health Checks

# Basic health check
curl http://localhost:3000/health

# Detailed status
curl http://localhost:3000/api/status

Logs

# View logs (PM2)
pm2 logs chatrtc-server

# View logs (direct)
tail -f logs/chatrtc-server.log

Troubleshooting

Common Issues

  1. Port already in use

    # Check what's using the port
    lsof -i :3000
    # Kill the process or change PORT in .env
    
  2. CORS errors from Android

    • Ensure ALLOWED_ORIGINS=* in .env
    • Check network security config in Android app
  3. Connection timeouts

    • Verify firewall settings
    • Check if port is accessible from client network
  4. Socket.IO connection fails

    • Enable polling transport as fallback
    • Check network connectivity
    • Verify server URL in Android app

Debug Mode

Enable detailed logging:

LOG_LEVEL=debug

Testing Connection

Use a Socket.IO client to test:

const io = require('socket.io-client');
const socket = io('http://localhost:3000');

socket.on('connect', () => {
    console.log('Connected to server');
    socket.emit('join-room', { nickname: 'TestUser' });
});

Development

Project Structure

server/
├── server.js              # Main server file
├── package.json           # Dependencies and scripts
├── ecosystem.config.js    # PM2 configuration
├── .env.example          # Environment template
├── .gitignore            # Git ignore rules
├── README.md             # This file
└── logs/                 # Log files (created automatically)

Contributing

  1. Fork the repository
  2. Create a feature branch
  3. Make your changes
  4. Add tests if applicable
  5. Submit a pull request

Running Tests

npm test

Code Style

npm run lint

License

MIT License - see LICENSE file for details.

Support

  • Create an issue on GitHub
  • Check the troubleshooting section
  • Review server logs for errors