Project: Real-time Chat Server
Overview
Build a production-grade real-time chat server with WebSocket support, horizontal scaling via Redis pub/sub, and MongoDB persistence. This project demonstrates real-time communication, distributed systems, and full-stack development.
What You'll Build:
- WebSocket-based real-time communication
- User authentication with JWT
- Chat rooms and private messaging
- Message persistence with MongoDB
- Redis pub/sub for multi-server scaling
- Rate limiting and security
- React-based web client
What You'll Learn:
- WebSocket protocol and implementation
- Real-time message broadcasting
- Distributed pub/sub patterns
- Authentication and authorization
- NoSQL database design
- Horizontal scaling strategies
- Cross-origin resource sharing
Problem Statement
Building real-time communication systems presents several unique challenges that differ from traditional request-response web applications. This project addresses the core problem: How do you build a scalable, reliable chat server that supports thousands of concurrent connections while maintaining message consistency across multiple server instances?
Key Challenges:
- Persistent Connections: Unlike HTTP requests, WebSocket connections remain open, requiring careful resource management
- Message Distribution: Messages must be delivered to all participants in a room in real-time
- Horizontal Scaling: Single-server solutions can't handle enterprise-scale traffic
- State Synchronization: Multiple server instances must share client state and message queues
- Connection Recovery: Clients must reconnect gracefully after network failures
- Security: Real-time systems need authentication without compromising performance
Real-World Applications:
- Team collaboration platforms
- Customer support live chat systems
- Gaming chat and multiplayer coordination
- Financial trading platforms with real-time updates
- Social media live messaging
- IoT device communication
Requirements
Functional Requirements
Core Features:
-
User Management
- User registration and login
- JWT-based authentication
- User profiles with avatars
- Online/offline status tracking
-
Chat Rooms
- Create public and private rooms
- Join and leave rooms
- List available rooms
- Room member management
-
Messaging
- Send and receive text messages in real-time
- Message persistence
- System messages
- Message timestamps
-
Real-time Features
- WebSocket connections for bidirectional communication
- Live message broadcasting to room members
- Connection status indicators
Non-Functional Requirements
Performance:
- Support 10,000+ concurrent WebSocket connections per server instance
- Message delivery latency < 100ms within the same server
- Message delivery latency < 500ms across different server instances
- Handle 1,000 messages per second throughput
Scalability:
- Horizontal scaling via Redis pub/sub
- Stateless server design
- Connection pooling for database access
- Efficient memory usage per connection
Reliability:
- Graceful connection handling and cleanup
- Automatic reconnection support
- Message delivery guarantees
- Error recovery and logging
Security:
- JWT token validation on WebSocket upgrade
- Input validation and sanitization
- Rate limiting per user
- CORS configuration for web clients
- Secure password hashing
Maintainability:
- Clean separation of concerns
- Comprehensive error handling
- Structured logging
- Docker containerization
Technical Constraints
Technology Stack:
- Backend: Go 1.19+ with standard library and minimal dependencies
- WebSocket: gorilla/websocket
- Database: MongoDB for persistence
- Pub/Sub: Redis for message distribution
- Authentication: JWT tokens
- HTTP Router: Chi or Gorilla Mux
- Frontend: React with native WebSocket API
Infrastructure:
- Containerized deployment with Docker
- Docker Compose for multi-service orchestration
- Environment-based configuration
- Non-root Docker user for security
API Design:
- RESTful HTTP endpoints for authentication and room management
- WebSocket endpoint for real-time messaging
- JSON message format for client-server communication
Design Considerations
System Architecture Overview
The chat server follows a distributed architecture with these key components:
1. WebSocket Server
- Handles persistent client connections
- Manages connection lifecycle
- Implements hub pattern for client orchestration
- Routes messages to appropriate rooms
2. Redis Pub/Sub Layer
- Enables message broadcasting across multiple server instances
- Decouples message producers from consumers
- Provides horizontal scaling capability
- Channel-based message routing
3. MongoDB Persistence
- Stores user accounts, chat rooms, and message history
- Provides message retrieval for reconnecting clients
- Supports search and analytics queries
- Ensures data durability
4. React Web Client
- WebSocket connection management
- User interface for chat rooms and messages
- JWT token storage and transmission
- Reconnection logic
High-Level Flow
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ Client 1 │◄──────►│ Server 1 │◄──────►│ Redis │
│ │ WS │ │ Pub │ │
└──────────────┘ └──────────────┘ Sub └──────────────┘
│ ▲
│ MongoDB │
▼ │
┌──────────────┐ ┌──────────────┐ │
│ Client 2 │◄──────►│ Server 2 │◄──────────────┘
│ │ WS │ │
└──────────────┘ └──────────────┘
Key Design Patterns
Hub Pattern:
- Central registry for all active WebSocket connections
- Manages client registration, unregistration, and broadcasting
- Uses channels for thread-safe communication
- Maintains room-to-clients mapping
Repository Pattern:
- Abstracts data access logic
- Separate repositories for Users, Messages, and Rooms
- Enables testing with mock repositories
- Clean separation from business logic
Middleware Chain:
- JWT validation middleware for protected routes
- CORS middleware for web client access
- Logging and recovery middleware
- Rate limiting middleware
Concurrent Read/Write Pumps:
- Separate goroutines for reading from and writing to WebSocket
- Prevents blocking operations
- Implements ping/pong for connection health
- Graceful shutdown on errors
Scalability Strategy
- Stateless Servers: JWT tokens eliminate server-side session storage
- Redis Fan-Out: Messages published once, received by all server instances
- Connection Pooling: Reuse database connections efficiently
- Buffered Channels: Prevent blocking on message broadcast
- Graceful Degradation: Continue operation if Redis is temporarily unavailable
Acceptance Criteria
Your implementation is complete when it meets these criteria:
✅ Core Functionality:
- Users can register accounts and log in successfully
- JWT tokens are generated, validated, and expire correctly
- Users can create and join chat rooms
- Messages are delivered in real-time to all room members
- Message history persists across server restarts
- System messages notify when users join or leave rooms
✅ Scalability:
- Running multiple server instances works without message duplication
- Messages broadcast across server instances via Redis pub/sub
- New server instances can join the cluster seamlessly
- Connection count scales to at least 1,000 concurrent connections in testing
✅ Security:
- Passwords are hashed with bcrypt before storage
- WebSocket connections require valid JWT tokens
- Invalid tokens are rejected with clear error messages
- Rate limiting prevents spam
- CORS is properly configured for the web client origin
✅ Reliability:
- WebSocket connections close gracefully on client disconnect
- Server shutdown drains existing connections properly
- Database connection failures are logged and recovered
- WebSocket read/write errors don't crash the server
- Clients can reconnect after network interruptions
✅ Code Quality:
- Code is organized into logical packages
- Errors include context and are logged appropriately
- No goroutine leaks
- Configuration uses environment variables
- README provides clear setup and running instructions
✅ Testing:
- Unit tests for JWT generation and validation
- Unit tests for message serialization/deserialization
- Integration tests for WebSocket connection flow
- Load test demonstrates 1,000+ concurrent connections
- Tests run successfully in CI environment
✅ Deployment:
- Docker Compose brings up all services
- Application runs as non-root user in Docker
- Environment variables configure MongoDB and Redis URLs
- Health check endpoint returns service status
- Logs are structured and readable
Usage Examples
Example 1: User Registration and Login
Register a new user:
1curl -X POST http://localhost:8080/api/auth/register \
2 -H "Content-Type: application/json" \
3 -d '{
4 "username": "alice",
5 "email": "alice@example.com",
6 "password": "SecurePass123!"
7 }'
Response:
1{
2 "id": "507f1f77bcf86cd799439011",
3 "username": "alice",
4 "email": "alice@example.com",
5 "created_at": "2025-01-15T10:30:00Z"
6}
Login:
1curl -X POST http://localhost:8080/api/auth/login \
2 -H "Content-Type: application/json" \
3 -d '{
4 "email": "alice@example.com",
5 "password": "SecurePass123!"
6 }'
Response:
1{
2 "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
3 "user": {
4 "id": "507f1f77bcf86cd799439011",
5 "username": "alice",
6 "email": "alice@example.com"
7 }
8}
Example 2: Create and Join Chat Room
Create a room:
1curl -X POST http://localhost:8080/api/rooms \
2 -H "Content-Type: application/json" \
3 -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." \
4 -d '{
5 "name": "General Discussion",
6 "description": "A place for general chat",
7 "is_private": false
8 }'
Response:
1{
2 "id": "507f1f77bcf86cd799439012",
3 "name": "General Discussion",
4 "description": "A place for general chat",
5 "creator_id": "507f1f77bcf86cd799439011",
6 "members": ["507f1f77bcf86cd799439011"],
7 "is_private": false,
8 "created_at": "2025-01-15T10:35:00Z"
9}
List available rooms:
1curl http://localhost:8080/api/rooms \
2 -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
Example 3: WebSocket Chat Communication
Connect to WebSocket:
1// JavaScript client example
2const token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...";
3const userId = "507f1f77bcf86cd799439011";
4const roomId = "507f1f77bcf86cd799439012";
5
6const ws = new WebSocket(
7 `ws://localhost:8080/ws?token=${token}&room_id=${roomId}`
8);
9
10ws.onopen = => {
11 console.log("Connected to chat server");
12};
13
14ws.onmessage = => {
15 const message = JSON.parse(event.data);
16 console.log(`[${message.username}]: ${message.content}`);
17};
18
19// Send a message
20const sendMessage = => {
21 const message = {
22 type: "message",
23 room_id: roomId,
24 content: content
25 };
26 ws.send(JSON.stringify(message));
27};
28
29sendMessage("Hello, everyone!");
Message received by all room members:
1{
2 "id": "507f1f77bcf86cd799439013",
3 "room_id": "507f1f77bcf86cd799439012",
4 "user_id": "507f1f77bcf86cd799439011",
5 "username": "alice",
6 "content": "Hello, everyone!",
7 "type": "text",
8 "timestamp": "2025-01-15T10:40:00Z"
9}
Example 4: Message History
Fetch room message history:
1curl "http://localhost:8080/api/rooms/507f1f77bcf86cd799439012/messages?limit=50&offset=0" \
2 -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
Response:
1{
2 "messages": [
3 {
4 "id": "507f1f77bcf86cd799439013",
5 "room_id": "507f1f77bcf86cd799439012",
6 "user_id": "507f1f77bcf86cd799439011",
7 "username": "alice",
8 "content": "Hello, everyone!",
9 "type": "text",
10 "timestamp": "2025-01-15T10:40:00Z"
11 },
12 {
13 "id": "507f1f77bcf86cd799439014",
14 "room_id": "507f1f77bcf86cd799439012",
15 "user_id": "507f1f77bcf86cd799439015",
16 "username": "bob",
17 "content": "Hi Alice!",
18 "type": "text",
19 "timestamp": "2025-01-15T10:41:00Z"
20 }
21 ],
22 "total": 2,
23 "offset": 0,
24 "limit": 50
25}
Example 5: Docker Deployment
Start all services:
1docker-compose up -d
Check service logs:
1docker-compose logs -f app
Scale to multiple instances:
1docker-compose up -d --scale app=3
Stop services:
1docker-compose down
Key Takeaways
Technical Skills Developed:
-
WebSocket Protocol Understanding
- Bidirectional persistent connections
- Connection upgrade handshake
- Message framing and binary/text modes
- Ping/pong for connection health
- Graceful closure and error handling
-
Distributed Systems Patterns
- Pub/Sub architecture for decoupling
- Horizontal scaling with shared state
- Stateless server design
- Message fan-out across instances
- Eventual consistency trade-offs
-
Real-time Communication
- Hub pattern for connection management
- Concurrent read/write pumps
- Buffered channels for non-blocking broadcast
- Room-based message routing
- Connection lifecycle management
-
Authentication and Security
- JWT token generation and validation
- Stateless authentication for WebSockets
- Token expiration and refresh strategies
- Rate limiting for abuse prevention
- Secure password hashing with bcrypt
-
Database Integration
- MongoDB document modeling
- Repository pattern for data access
- Connection pooling for efficiency
- Indexing for query performance
- Message pagination for history
-
Concurrent Programming
- Goroutines for per-connection handlers
- Channels for synchronization
- Mutex for shared state protection
- Race condition detection
- Resource cleanup and leak prevention
-
Production Engineering
- Graceful shutdown handling
- Structured logging for debugging
- Health check endpoints
- Docker containerization
- Environment-based configuration
Architecture Insights:
- Separation of Concerns: Clear boundaries between transport, business logic, and persistence
- Scalability First: Redis pub/sub enables horizontal scaling from day one
- Failure Isolation: Component failures don't crash the entire system
- Observability: Structured logs and metrics points for monitoring
- Security Depth: Multiple layers
Next Steps
Feature Enhancements
-
Rich Media Support
- File uploads with size limits
- Image previews and thumbnails
- Voice message recording
- Video calling with WebRTC
- Screen sharing capabilities
-
Advanced Chat Features
- Typing indicators
- Read receipts and delivery status
- Message reactions
- Threaded conversations
- Message editing and deletion
- Search across message history
- @mentions and notifications
-
User Experience
- User presence tracking
- Last seen timestamps
- User profiles and settings
- Custom avatars and themes
- Desktop notifications
- Unread message counters
Security Improvements
-
Enhanced Authentication
- OAuth2 integration
- Two-factor authentication
- Session management and revocation
- Token refresh mechanism
- IP whitelisting for admin users
-
Content Security
- End-to-end encryption for private messages
- Message content scanning for spam/abuse
- XSS protection with input sanitization
- Content Security Policy headers
- Rate limiting per user and per IP
-
Compliance
- GDPR-compliant data deletion
- Message retention policies
- Audit logs for compliance
- Data encryption at rest
Performance Optimizations
-
Scaling Strategies
- Connection pooling for Redis and MongoDB
- Message batching to reduce round trips
- Lazy loading for message history
- CDN for static assets
- Load balancing with health checks
-
Caching
- Redis cache for user sessions
- Message cache for recent messages
- Room metadata caching
- Cache invalidation strategies
-
Database Optimization
- Compound indexes for common queries
- Sharding for high-volume deployments
- Read replicas for message history
- Archive old messages to cold storage
Monitoring and Observability
-
Metrics
- Prometheus metrics for:
- Active WebSocket connections
- Messages per second
- Redis pub/sub latency
- Database query performance
- Error rates by type
- Grafana dashboards for visualization
- Prometheus metrics for:
-
Logging
- Structured logging with correlation IDs
- Log aggregation
- Request tracing with OpenTelemetry
- Error tracking
-
Alerting
- High error rate alerts
- Connection pool exhaustion
- Redis/MongoDB downtime
- Memory/CPU usage thresholds
Testing Expansion
-
Test Coverage
- Unit tests for business logic
- Integration tests for WebSocket flow
- Load tests with thousands of concurrent connections
- Chaos engineering
- E2E tests with Playwright or Cypress
-
Performance Testing
- Benchmark message throughput
- Measure latency percentiles
- Test failover scenarios
- Memory leak detection over extended runs
Production Deployment
-
Kubernetes Deployment
- Kubernetes manifests for production
- Horizontal Pod Autoscaler for scaling
- Redis Sentinel for high availability
- MongoDB replica set for durability
- Ingress controller for HTTPS
-
CI/CD Pipeline
- Automated testing on pull requests
- Docker image builds and registry push
- Canary deployments for zero downtime
- Rollback strategies for failed deployments
Learning Extensions
-
Related Projects
- Video Conferencing: Integrate WebRTC for peer-to-peer video
- Notification Service: Real-time push notifications via WebSockets
- Collaborative Editing: Operational transformation for shared documents
- Live Dashboard: Real-time analytics with WebSocket updates
-
Advanced Topics
- CRDT: For distributed consistency
- Event Sourcing: Store all message events for replay
- gRPC Streaming: Alternative to WebSockets for server-to-server communication
- GraphQL Subscriptions: Combine REST/GraphQL with real-time subscriptions
Download Complete Solution
📦 Download Complete Solution
Get the full production-ready implementation with all source files:
⬇️ Download SolutionIncludes:
- Complete Go backend with all packages
- React web client with styled components
- Docker Compose configuration for all services
- Comprehensive README with architecture details, setup instructions, and deployment guide
- Unit and integration tests
- Environment configuration templates
Quick Start: Extract the zip, run docker-compose up, and visit http://localhost:3000. See README for detailed implementation guide and customization options.