Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Workspace-level environment variables
NODE_ENV=development
ENABLE_LOGGING=true
LOG_LEVEL=info
31 changes: 13 additions & 18 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,23 +1,18 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# dependencies
/node_modules
/.pnp
.pnp.js

# testing
/coverage

# production
/build

# misc
node_modules/
dist/
build/
.DS_Store
.env
.env.local
.env.development.local
.env.test.local
.env.production.local

npm-debug.log*
yarn-debug.log*
yarn-error.log*
.pnpm-debug.log*
# Environment files
.env
.env.local
.env.development
.env.test
.env.production
# Keep examples in git
!.env.example
64 changes: 64 additions & 0 deletions ARCHITECTURE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# Architecture Documentation

## Overview
This project enables real-time screen sharing between a client and a host using WebRTC for media transport and Socket.IO for signaling. The architecture is modular, with clear separation between UI, signaling, and communication logic.

## Components

### 1. Client (apps/client)
- React app that allows a user to share their screen.
- Uses WebRTC to capture and send the screen stream.
- Connects to the signaling server via Socket.IO for signaling (offer, answer, ICE).

### 2. Host (apps/host)
- React app that receives and displays the shared screen.
- Connects to the signaling server via Socket.IO for signaling.
- Handles incoming WebRTC streams and renders them in a video element.

### 3. Signaling Server (apps/signaling-server)
- Node.js server using Socket.IO.
- Relays signaling messages (offer, answer, ICE candidates) between client and host.
- Handles client/host registration and connection management.

### 4. Shared Packages
- `@webrtc-project/communication`: Shared communication protocol logic.
- `@webrtc-project/shared-types`: Shared TypeScript types.
- `@webrtc-project/ui-components`: Shared UI components (Card, Button, etc).

## Flow Diagram

```
Client <---Socket.IO---> Signaling Server <---Socket.IO---> Host
| |
|--- getDisplayMedia (screen) ---+ |
| | |
|--- createOffer --------------->| |
| |--- forward offer ---->|
| |<-- answer ------------|
|<-- answer ---------------------| |
|--- ICE candidates ------------>|--- ICE candidates --->|
|<-- ICE candidates -------------|<-- ICE candidates ----|
| |
|--- WebRTC Media Stream ------->|--- WebRTC Media ----->|
```

## Sequence
1. Client and Host connect to the signaling server and register their roles.
2. Client starts screen sharing, creates a WebRTC offer, and sends it via the signaling server.
3. Host receives the offer, creates an answer, and sends it back via the signaling server.
4. Both peers exchange ICE candidates for NAT traversal.
5. Once the connection is established, the Host receives and displays the Client's screen stream.

## Security
- Only registered clients/hosts can exchange signaling messages.
- CORS and rate limiting are enabled on the signaling server.
- WebRTC streams are peer-to-peer and encrypted.

## Extensibility
- The architecture supports adding chat, file transfer, or multi-user features by extending the signaling and communication logic.

## Testing
- Each module includes unit tests for connection, signaling, and UI logic.

---
For more details, see the code and README.
51 changes: 51 additions & 0 deletions ENV_SETUP.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# Environment Setup

This monorepo uses a hierarchical environment configuration approach.

## Configuration Hierarchy

Environment variables are loaded in the following order, with later configs overriding earlier ones:

1. Workspace-level environment variables (root `.env` files)
2. App-specific base environment variables (apps/{app}/config/.env)
3. App-specific environment-specific variables (apps/{app}/config/.env.{environment})

## Development Setup

1. Copy example files to create your local environment:

```bash
# Root workspace
cp .env.example .env

# Host application
cp apps/host/config/.env.example apps/host/config/.env
cp apps/host/config/.env.example apps/host/config/.env.development

# Client application
cp apps/client/config/.env.example apps/client/config/.env
cp apps/client/config/.env.example apps/client/config/.env.development
```

2. Modify the environment files as needed for your local setup

3. Start the development server with:

```bash
pnpm dev
```

## Adding New Environment Variables

When adding new environment variables:

1. Add them to the respective `.env.example` file
2. Add them to the corresponding environment utility in `src/utils/env.ts`
3. Update this README if necessary

## Production Deployment

For production deployments:

1. Create `.env.production` files for each application
2. Set `NODE_ENV=production` in your deployment environment
88 changes: 85 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,88 @@
# WEBRTC implementation in REACTJS
# WebRTC Screen Sharing App

yarn install
yarn start
## Overview
This project implements a screen sharing application using WebRTC for peer-to-peer media streaming and Socket.IO for signaling. It consists of three main components:
- **Client**: Initiates screen sharing and sends the stream.
- **Host**: Receives and displays the shared screen.
- **Signaling Server**: Relays signaling messages (offer, answer, ICE candidates) between peers using Socket.IO.

## Architecture Flow

```
+---------+ +-------------------+ +------+
| Client | <-----> | Signaling Server | <-----> | Host |
+---------+ +-------------------+ +------+
| | |
|---(Socket.IO join)-->| |
|<--(registered)-------| |
|---(offer)----------->| |
| |---(offer)------------->|
| |<--(answer)-------------|
|<--(answer)-----------| |
|---(ICE candidate)----| |
| |---(ICE candidate)----->|
| |<--(ICE candidate)------|
|<--(ICE candidate)----| |
```

- The **Client** captures the screen and sends an offer via the signaling server.
- The **Host** receives the offer, creates an answer, and sends it back.
- Both peers exchange ICE candidates for connectivity.
- Once connected, the Host displays the Client's shared screen.

## Getting Started

### Prerequisites
- Node.js (v16+ recommended)
- pnpm (or npm/yarn)

### Install Dependencies
```bash
pnpm install
```

### Run Signaling Server
```bash
cd apps/signaling-server
pnpm start
```

### Run Client
```bash
cd apps/client
pnpm dev
```

### Run Host
```bash
cd apps/host
pnpm dev
```

- Client: http://localhost:4000
- Host: http://localhost:3000
- Signaling Server: http://localhost:4000 (API)

## Usage
- Open the Host and Client in separate browser windows.
- On the Client, click "Start Screen Share" to share your screen.
- The Host will display the shared screen in real time.

## Testing
To run unit tests for all modules:
```bash
pnpm test
```

## Project Structure
- `apps/client`: React client app for screen sharing
- `apps/host`: React host app to view shared screen
- `apps/signaling-server`: Node.js Socket.IO signaling server
- `packages/communication`: Shared communication logic
- `packages/shared-types`: Shared TypeScript types
- `packages/ui-components`: Shared UI components

## License
MIT


7 changes: 7 additions & 0 deletions apps/client/config/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Client Application Environment Variables
CLIENT_PORT=3001
HOST_ORIGIN=http://localhost:3000
DEBUG_MODE=false
# WebRTC Configuration
ICE_SERVERS=[{"urls":["stun:stun1.example.com:19302","stun:stun2.example.com:19302"]}]
SIGNALING_SERVER=wss://example.com/signaling
13 changes: 13 additions & 0 deletions apps/client/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Your Client App</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="src/index.tsx"></script>
</body>
</html>
26 changes: 26 additions & 0 deletions apps/client/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
"name": "@webrtc-project/client",
"version": "0.0.1",
"scripts": {
"dev": "vite",
"build": "tsc && vite build",
"serve": "vite preview"
},
"dependencies": {
"@webrtc-project/communication": "workspace:*",
"@webrtc-project/shared-types": "workspace:*",
"@webrtc-project/ui-components": "workspace:*",
"dotenv": "^16.0.3",
"dotenv-expand": "^10.0.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"socket.io-client": "^4.8.1"
},
"devDependencies": {
"@types/react": "^18.0.25",
"@types/react-dom": "^18.0.9",
"@vitejs/plugin-react": "^2.2.0",
"typescript": "^4.9.3",
"vite": "^3.2.4"
}
}
2 changes: 2 additions & 0 deletions apps/client/src/App.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
declare function App(): import("react/jsx-runtime").JSX.Element;
export default App;
15 changes: 15 additions & 0 deletions apps/client/src/App.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import React from 'react';
import { render, screen, fireEvent } from '@testing-library/react';
import App from './App';

describe('Client App', () => {
it('renders screen share button', () => {
render(<App />);
expect(screen.getByText(/Start Screen Share/i)).toBeInTheDocument();
});

it('shows logs area', () => {
render(<App />);
expect(screen.getByText(/Communication Logs/i)).toBeInTheDocument();
});
});
Loading