Backend
Backend Server
Bun + TypeScript backend server with WebSocket support, Redis integration, and cryptographic authentication.
Core Components
DataManager (dataManager.ts)
Handles all data operations with automatic cleanup and caching:
- TTL Management: Automatic expiration of clients (35s), rooms (2h), and messages (24h)
- Cleanup Operations: Periodic cleanup of expired data every 60 seconds
- Room Management: Client-to-room associations and message persistence
- Private Messaging: Direct client-to-client communication
CommandHandler (commandHandler.ts)
Processes WebSocket commands with authentication:
- Authentication Flow: RSA signature verification for all commands
- Room Operations: Create, join, leave rooms with real-time notifications
- Message Handling: Room messages and private messages with file support
- Session Security: WebSocket session binding to prevent hijacking
Storage Layer (storage.ts)
Dual-mode storage system (Redis + Local):
- Redis Integration: Distributed storage with connection fallback
- Local Storage: In-memory maps for offline operation
- Caching Layer: 30-second TTL cache with LRU eviction
- Batch Operations: Optimized bulk operations for performance
Configuration
export const CONFIG = {
CLIENT_TTL: 35, // Client session timeout (seconds)
ROOM_TTL: 7200, // Room inactivity timeout (2 hours)
MESSAGE_TTL: 86400, // Message retention (24 hours)
DEBUG: process.env.DEBUG || false,
SERVER: {
PORT: process.env.PORT || 5000,
HOST: process.env.HOST || '0.0.0.0'
},
REDIS: {
HOST: process.env.REDIS_HOST || 'redis',
PORT: process.env.REDIS_PORT || 6379,
PASSWORD: process.env.REDIS_PASSWORD || 'password',
DB: process.env.REDIS_DB || 0
}
};Data Models
Client Model
interface Client {
id: string; // Unique username
public_key: string; // RSA public key (PEM format)
ecdh_key?: string; // Optional ECDH key
room_id: string | null; // Current room assignment
last_seen: string; // ISO timestamp
created_at: string; // Registration timestamp
online?: boolean; // Online status
}Room Model
interface Room {
clients: { [clientId: string]: ClientInRoom };
messages: Message[];
created_at: string;
last_activity: string;
}Message Model
interface Message {
from_client: string; // Sender identifier
text: string; // Message content
signature?: string; // Cryptographic signature
timestamp: string; // ISO timestamp
public_key: string; // Sender's public key
verified?: boolean; // Signature verification status
file?: boolean; // File attachment flag
filename?: string; // File name
mimetype?: string; // MIME type
content?: string; // Base64 file content
}Redis Integration
Data Storage Patterns
Key Naming Convention
client:{client_id} # Client data
room:{room_id} # Room data
pm:{message_id} # Private messages
room_clients:{room_id} # Room membership index
user_messages:{user_id} # User message indexCaching Strategy
- Cache TTL: 30 seconds for frequently accessed data
- Cache Size: Maximum 1000 entries with LRU eviction
- Write-Through: Updates both cache and persistent storage
- Fallback Mode: Automatic local storage when Redis unavailable
WebSocket Implementation
Connection Lifecycle
export const websocket: WebSocketHandler<WebSocketData> = {
open(ws) {
printDebug(`[WS] Connection opened.`);
ws.subscribe("global");
},
message(ws, message) {
commandHandler.handle(ws, message, wsClientMap);
},
ping(ws, data) {
ws.pong(data);
},
close(ws, code, reason) {
const clientId = ws.data.clientId;
if (clientId) wsClientMap.delete(clientId);
},
};Session Management
- WebSocket Binding: Each WebSocket bound to authenticated client
- Session Validation: Continuous validation of client-session binding
- Automatic Cleanup: Expired sessions automatically removed
- Connection Tracking: Real-time tracking of active connections
Performance Features
Caching Strategy
- Client Cache: 30-second TTL with 1000-entry limit
- Room Cache: Frequently accessed room data cached
- Redis Pipeline: Batch operations for improved performance
- Connection Pooling: Persistent connections to Redis
Memory Management
- Cleanup Intervals: 60-second cleanup cycles
- TTL Enforcement: Automatic expiration of old data
- Cache Eviction: LRU eviction when cache limits reached
- Resource Monitoring: Continuous monitoring of memory usage
Error Handling
Connection Management
- Automatic Fallback: Redis → Local storage fallback
- Graceful Degradation: System continues operating without Redis
- Connection Recovery: Automatic reconnection attempts
- Error Logging: Comprehensive error tracking and reporting
Data Integrity
- Transaction Safety: Redis transactions for data consistency
- Validation Layers: Input validation at multiple levels
- Cleanup Procedures: Automatic cleanup of orphaned data
- State Synchronization: Consistent state across distributed components
Docker Configuration
Dockerfile
FROM oven/bun:alpine
WORKDIR /app
RUN apk update && apk add --no-cache curl
COPY package.json bun.lock ./
RUN bun install
COPY . .
CMD ["bun", "run", "index.ts"]Dependencies
{
"dependencies": {
"dotenv": "^17.2.1",
"ioredis": "^5.7.0",
"redis": "^5.8.1",
"uuid": "^11.1.0",
"ws": "^8.18.3"
}
}Development Commands
# Local development
bun install
bun run index.ts
# Docker development
docker compose up server --build
docker compose logs -f server
# Debug mode
DEBUG=TRUE bun run index.ts