This document describes the API endpoints and Socket.io events for the Live Loop video calling application.
Development: http://localhost:3000
Production: https://your-domain.com
Check if the server is running and healthy.
Endpoint: GET /
Response:
{
status: "OK",
message: "Hello, TypeScript!"
}Get current system status including queue and room information.
Endpoint: GET /api/status
Response:
{
queue: {
size: 5,
users: ["user1", "user2", "user3"]
},
rooms: {
active: 10,
total: 15
},
timestamp: "2025-01-17T10:00:00Z"
}Request to join a room and find a match.
Event: request-room
Payload:
{
name: string, // User's display name
roomId: string | null, // Previous room ID (if rejoining)
userImage: string // Base64 encoded user thumbnail
}Description: Adds user to the matchmaking queue and attempts to find a match.
Send WebRTC offer to establish peer connection.
Event: negotiation-call-offer
Payload:
{
offer: RTCSessionDescriptionInit, // WebRTC offer
roomId: string, // Room identifier
name: string, // User's name
remoteSocketId: string // Target user's socket ID
}Send WebRTC answer to complete peer connection.
Event: negotiation-call-answer
Payload:
{
ans: RTCSessionDescriptionInit, // WebRTC answer
roomId: string, // Room identifier
name: string, // User's name
remoteSocketId: string // Target user's socket ID
}Send ICE candidates for NAT traversal.
Event: send-new-ice-candidates
Payload:
{
to: string, // Target socket ID
candidate: RTCIceCandidate // ICE candidate
}End the current call session.
Event: stop-call
Payload:
{
roomId: string, // Room identifier
remoteSocketId: string, // Remote user's socket ID
name: string // User's name
}Send a chat message during the call.
Event: newMessage
Payload:
{
message: string, // Chat message content
roomId: string, // Room identifier
remoteSocket: string // Remote user's socket ID
}Notify that a match has been found.
Event: match-done
Payload:
{
roomId: string, // Room identifier
remoteUserDetails: {
socket: string, // Remote user's socket ID
userName: string, // Remote user's name
userImage: string // Remote user's thumbnail
}
}Receive WebRTC offer from remote user.
Event: negotiation-call-offer
Payload:
{
remoteUserDetails: {
socket: string, // Remote user's socket ID
userName: string // Remote user's name
},
roomId: string, // Room identifier
offer: RTCSessionDescriptionInit // WebRTC offer
}Receive WebRTC answer from remote user.
Event: negotiation-call-answer
Payload:
{
ans: RTCSessionDescriptionInit, // WebRTC answer
roomId: string, // Room identifier
name: string, // Remote user's name
remoteSocketId: string // Remote user's socket ID
}Receive ICE candidates from remote user.
Event: new-ice-candidates
Payload:
{
candidate: RTCIceCandidate // ICE candidate
}Notification that the remote user ended the call.
Event: stop-by-remote-user
Payload: None
Receive a chat message from remote user.
Event: Message:recived
Payload:
{
from: string, // Sender's socket ID
message: string // Message content
}Client connects → Server assigns socket ID → Client joins general room
Client: request-room
↓
Server: Adds to queue → Attempts matching
↓
Server: match-done (to both users)
↓
Clients: Setup WebRTC connection
User A: negotiation-call-offer
↓
Server: Forward to User B
↓
User B: negotiation-call-answer
↓
Server: Forward to User A
↓
Both users exchange ICE candidates
↓
P2P connection established
User A: newMessage
↓
Server: Broadcast to both users
↓
Both users: Message:recived
User A: stop-call
↓
Server: stop-by-remote-user (to User B)
↓
Both users: Clean up connections
↓
Server: Re-add users to queue (optional)
- Connection timeout: Automatic reconnection attempt
- Invalid room: Error message to user
- Queue full: User notified to try again later
- Offer/Answer failure: Connection retry
- ICE candidate failure: Fallback to TURN server
- Media access denied: User notification
- Message delivery failure: Retry mechanism
- Invalid message format: Client-side validation
- request-room: 1 request per 5 seconds
- newMessage: 10 messages per minute
- ICE candidates: No limit (essential for connectivity)
- Always handle event errors gracefully
- Implement reconnection logic for socket disconnections
- Validate all payloads before sending
- Clean up resources when connections end
- Use appropriate timeouts for WebRTC operations
// Example test using socket.io-client
const io = require('socket.io-client');
const client = io('http://localhost:3000');
client.emit('request-room', {
name: 'Test User',
roomId: null,
userImage: 'data:image/png;base64,...'
});
client.on('match-done', (data) => {
console.log('Match found:', data);
});// Test WebRTC offer creation
const peerConnection = new RTCPeerConnection({
iceServers: [
{ urls: 'stun:stun.l.google.com:19302' }
]
});
const offer = await peerConnection.createOffer();
await peerConnection.setLocalDescription(offer);