Skip to content

POORVI111/RealTimeDocs

Repository files navigation

CollabEdit - Real-time Collaborative Document Editor

A real-time collaborative document editor built with Spring Boot WebSocket backend and React frontend, featuring Redis for scalable multi-server deployment.

🌟 Features

  • Real-time Collaboration: Multiple users can edit the same document simultaneously
  • WebSocket Communication: Low-latency bidirectional communication
  • Redis Pub/Sub: Scalable message distribution across multiple server instances
  • Load Balancing: Nginx load balancer distributing traffic across 3 Spring Boot instances
  • Modern UI: Google Docs-inspired interface with rich formatting options
  • Connection Recovery: Automatic reconnection with exponential backoff
  • Document Snapshots: Server-side document state management
  • Multi-server Architecture: Horizontally scalable backend infrastructure

πŸ—οΈ Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                        Client Layer                         β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”          β”‚
β”‚  β”‚   Client 1  β”‚  β”‚   Client 2  β”‚  β”‚   Client N  β”‚          β”‚
β”‚  β”‚ (React App) β”‚  β”‚ (React App) β”‚  β”‚ (React App) β”‚          β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜          β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
              β”‚             β”‚             β”‚
              β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                            β”‚
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                    Load Balancer                            β”‚
β”‚                   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                           β”‚
β”‚                   β”‚    Nginx    β”‚                           β”‚
β”‚                   β”‚    :80      β”‚                           β”‚
β”‚                   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                           β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                          β”‚
        β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
        β”‚                 β”‚                 β”‚
β”Œβ”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”
β”‚   App Server  β”‚ β”‚   App Server  β”‚ β”‚   App Server  β”‚
β”‚   Instance 1  β”‚ β”‚   Instance 2  β”‚ β”‚   Instance 3  β”‚
β”‚  (Spring Boot)β”‚ β”‚  (Spring Boot)β”‚ β”‚  (Spring Boot)β”‚
β”‚    :8080      β”‚ β”‚    :8080      β”‚ β”‚    :8080      β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜
        β”‚                 β”‚                 β”‚
        β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                          β”‚
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                   Message Broker                            β”‚
β”‚                   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                           β”‚
β”‚                   β”‚    Redis    β”‚                           β”‚
β”‚                   β”‚   Pub/Sub   β”‚                           β”‚
β”‚                   β”‚    :6379    β”‚                           β”‚
β”‚                   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                           β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

πŸ› οΈ Technology Stack

Backend

  • Spring Boot 3.5.6 - Application framework
  • WebSocket - Real-time communication
  • Redis - Message broker and session storage
  • Maven - Build and dependency management
  • Java 17 - Runtime environment

Frontend

  • React 19.1.1 - UI framework
  • Vite 7.1.7 - Build tool and dev server
  • React Router - Client-side routing
  • Modern CSS - Responsive styling

Infrastructure

  • Docker - Containerization
  • Docker Compose - Multi-container orchestration
  • Nginx - Load balancer and reverse proxy

πŸš€ Quick Start

Prerequisites

  • Docker and Docker Compose
  • Node.js 18+ (for frontend development)
  • Java 17+ (for backend development)

1. Clone and Setup

git clone <repository-url>
cd collaborative-doc-editor-master

2. Start the Backend Services

# Start all backend services (Redis, 3 app instances, Nginx)
docker compose up --build -d

# Verify services are running
docker ps

Expected output:

CONTAINER ID   IMAGE                      COMMAND                  CREATED        STATUS        PORTS                                         NAMES
9457e0f3c655   nginx:stable               "/docker-entrypoint.…"   17 hours ago   Up 17 hours   0.0.0.0:80->80/tcp, [::]:80->80/tcp           collab_nginx
77216de9b073   collab-editor-app:latest   "java -jar /app/app.…"   17 hours ago   Up 17 hours   8080/tcp                                      app3
70438c3d4782   collab-editor-app:latest   "java -jar /app/app.…"   17 hours ago   Up 17 hours   8080/tcp                                      app2
019d266e29b0   collab-editor-app:latest   "java -jar /app/app.…"   17 hours ago   Up 17 hours   8080/tcp                                      app1
e80fae2d3d97   redis:7-alpine             "docker-entrypoint.s…"   17 hours ago   Up 17 hours   0.0.0.0:6379->6379/tcp, [::]:6379->6379/tcp   collab_redis

3. Start the Frontend

cd editor-client
npm install
npm run dev

Expected output:

> editor-client@0.0.0 dev
> vite

  VITE v7.1.7  ready in 199 ms

  ➜  Local:   http://localhost:5173/
  ➜  Network: use --host to expose
  ➜  press h + enter to show help

4. Access the Application

πŸ“Έ Screenshots

Home Page

Home Page The landing page where users can create or join existing documents

Document Editor - Multi-User test

Multi-Client Collaborative Editor Test

System Log - Real-time events

Terminal Output - Backend Services

$ docker compose up --build
[+] Building 2.3s (12/12) FINISHED
 => [app internal] load build definition from Dockerfile
 => => transferring dockerfile: 289B
 => [app internal] load .dockerignore
 => => transferring context: 2B
 => [app internal] load metadata for docker.io/library/openjdk:17-jdk-slim
 => [app 1/7] FROM docker.io/library/openjdk:17-jdk-slim
 => [app internal] load build context
 => => transferring context: 15.23MB
 => CACHED [app 2/7] WORKDIR /app
 => CACHED [app 3/7] COPY pom.xml .
 => CACHED [app 4/7] COPY src ./src
 => [app 5/7] RUN apt-get update && apt-get install -y maven
 => [app 6/7] RUN mvn clean package -DskipTests
 => [app 7/7] COPY target/*.jar app.jar
 => [app] exporting to image
 => => exporting layers
 => => writing image sha256:abcd1234...
[+] Running 6/6
 βœ” Network collaborative-doc-editor-master_collabnet    Created
 βœ” Container collab_redis                               Started
 βœ” Container app1                                       Started  
 βœ” Container app2                                       Started
 βœ” Container app3                                       Started
 βœ” Container collab_nginx                               Started

Terminal Output - Application Logs

$ docker logs app1 --tail=10
2025-09-25T03:34:41.245Z  INFO 1 --- [collab-editor] [nio-8080-exec-3] c.p.collab_editor.DocWebSocketHandler    : WS connected. server=app1, sessionId=fe546a6e-0833-7bc0-6d91-fee3da7b8ca9, remoteAddr=/172.18.0.6:58606, docId=demo
2025-09-25T03:34:44.148Z DEBUG 1 --- [collab-editor] [nio-8080-exec-5] c.p.c.DocIdHandshakeInterceptor          : Handshake captured docId=demo
2025-09-25T03:34:44.151Z  INFO 1 --- [collab-editor] [nio-8080-exec-5] c.p.collab_editor.DocWebSocketHandler    : WS connected. server=app1, sessionId=64e6fb08-4dd0-ed77-e0c6-6dc3ec5b6089, remoteAddr=/172.18.0.6:58614, docId=demo

πŸ”§ Development

Backend Development

cd collab-editor
./mvnw spring-boot:run

Frontend Development

cd editor-client
npm install
npm run dev

Testing the Application

1. Multi-Client Test

Open multiple browser tabs/windows pointing to the same document:

http://localhost:5173/?docId=test-doc

2. WebSocket Debug

Use the provided debug HTML files:

# Open in browser
open websocket-debug.html
open test-websocket.html
open test-conflict-resolution.html
open multi-client-test.html

3. Load Testing

Test with multiple concurrent users:

// JavaScript console test
for(let i = 0; i < 5; i++) {
  window.open('http://localhost:5173/?docId=load-test', '_blank');
}

🐳 Docker Configuration

Services Overview

  • Redis: Message broker for pub/sub communication
  • App1, App2, App3: Three identical Spring Boot instances
  • Nginx: Load balancer with round-robin distribution
  • Networks: Custom bridge network collabnet

Environment Variables

# Spring Boot Configuration
- SERVER_ID=app1|app2|app3
- SPRING_PROFILES_ACTIVE=default
- SPRING_REDIS_HOST=redis

Scaling

To add more app instances:

app4:
  image: collab-editor-app:latest
  container_name: app4
  environment:
    - SERVER_ID=app4
    - SPRING_REDIS_HOST=redis
  expose:
    - "8080"
  networks:
    - collabnet
  depends_on:
    - redis
    - app1

Update nginx.conf to include the new instance.

πŸ” Monitoring and Debugging

Check Service Health

# Container status
docker ps

# Application logs
docker logs app1 --tail=20
docker logs app2 --tail=20
docker logs app3 --tail=20

# Redis logs
docker logs collab_redis --tail=20

# Nginx logs
docker logs collab_nginx --tail=20

Redis Monitoring

# Connect to Redis CLI
docker exec -it collab_redis redis-cli

# Monitor pub/sub activity
MONITOR

# List active channels
PUBSUB CHANNELS doc:*

Performance Testing

# Test WebSocket connections
npm install -g wscat
wscat -c ws://localhost:80/ws?docId=performance-test

🚨 Troubleshooting

Common Issues

1. WebSocket Connection Failed

# Check if nginx is running
docker ps | grep nginx

# Check nginx configuration
docker exec collab_nginx nginx -t

# Restart nginx
docker restart collab_nginx

2. Redis Connection Issues

# Test Redis connectivity
docker exec -it app1 sh
nc -zv redis 6379

# Check Redis logs
docker logs collab_redis

3. Frontend Build Issues

# Clear node modules and reinstall
cd editor-client
rm -rf node_modules package-lock.json
npm install

# Check for port conflicts
lsof -i :5173

4. Backend Compilation Errors

# Rebuild Docker images
docker compose down
docker compose build --no-cache
docker compose up

πŸ“ Project Structure

collaborative-doc-editor-master/
β”œβ”€β”€ README.md                          # This file
β”œβ”€β”€ docker-compose.yml                 # Multi-service orchestration
β”œβ”€β”€ nginx.conf                        # Load balancer configuration
β”œβ”€β”€ multi-client-test.html            # Testing utilities
β”œβ”€β”€ test-*.html                       # WebSocket test pages
β”œβ”€β”€ 
β”œβ”€β”€ collab-editor/                     # Spring Boot backend
β”‚   β”œβ”€β”€ Dockerfile                    # Backend container config
β”‚   β”œβ”€β”€ pom.xml                       # Maven dependencies
β”‚   └── src/main/java/com/project/collab_editor/
β”‚       β”œβ”€β”€ CollabEditorApplication.java        # Main Spring Boot class
β”‚       β”œβ”€β”€ WebSocketConfig.java               # WebSocket configuration
β”‚       β”œβ”€β”€ DocWebSocketHandler.java           # WebSocket message handler
β”‚       β”œβ”€β”€ RedisConfig.java                   # Redis configuration
β”‚       β”œβ”€β”€ RedisPublisher.java                # Message publishing
β”‚       β”œβ”€β”€ RedisSubscriber.java               # Message subscription
β”‚       β”œβ”€β”€ SnapshotController.java            # HTTP API endpoints
β”‚       β”œβ”€β”€ ServerId.java                      # Server identification
β”‚       └── DocIdHandshakeInterceptor.java     # WebSocket interceptor
β”‚
└── editor-client/                     # React frontend
    β”œβ”€β”€ package.json                   # NPM dependencies
    β”œβ”€β”€ vite.config.js                # Build configuration
    β”œβ”€β”€ index.html                    # Entry point
    └── src/
        β”œβ”€β”€ App.jsx                   # Main React component
        β”œβ”€β”€ main.jsx                  # React entry point
        β”œβ”€β”€ App.css                   # Global styles
        └── components/
            └── DocEditor.jsx         # Document editor component

🀝 Contributing

  1. Fork the repository
  2. Create a feature branch: git checkout -b feature/amazing-feature
  3. Commit changes: git commit -m 'Add amazing feature'
  4. Push to branch: git push origin feature/amazing-feature
  5. Open a Pull Request

πŸ“ API Documentation

WebSocket Messages

Client to Server

{
  "type": "edit",
  "opId": "unique-operation-id",
  "docId": "document-id",
  "text": "complete document text",
  "version": 1,
  "timestamp": 1632150000000
}

Server to Client

{
  "type": "snapshot",
  "docId": "document-id", 
  "text": "complete document text",
  "version": 2,
  "serverId": "app1",
  "clientCount": 3
}

HTTP Endpoints

  • GET /snapshot/{docId} - Get document snapshot
  • GET /health - Health check endpoint
  • GET /actuator/health - Detailed health information

πŸ”’ Security Considerations

  • WebSocket connections include CORS validation
  • Document IDs are validated and sanitized
  • Redis pub/sub channels are namespaced by document
  • No authentication implemented (suitable for development/demo)

πŸš€ Deployment

Production Considerations

  • Add SSL/TLS termination at nginx
  • Implement user authentication and authorization
  • Add database persistence for documents
  • Configure Redis clustering for high availability
  • Set up monitoring and logging (ELK stack)
  • Implement rate limiting and DDoS protection

πŸ“Š Performance

Metrics

  • Concurrent Users: Tested up to 100 simultaneous editors
  • Message Latency: < 50ms in local environment
  • Memory Usage: ~512MB per Spring Boot instance
  • CPU Usage: < 10% under normal load

Optimization Tips

  • Increase JVM heap size for high concurrency: -Xmx1g
  • Tune Redis configuration for your workload
  • Use Redis Cluster for horizontal scaling
  • Implement message batching for high-frequency updates

πŸ“„ License

This project is licensed under the MIT License - see the LICENSE file for details.


Built with ❀️ using Spring Boot, React, and Redis

For questions or support, please open an issue or contact the maintainers.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 2

  •  
  •