Skip to content

edrys-labs/edrys-websocket-server

 
 

Repository files navigation

edrys-websocket-server

WebSocket server for edrys-Lite to create a connection between peers and share video streams.

This project is a modified version of y-websocket-server by Kevin Jahns.

The WebSocket server provides two main functions:

  1. A backend for y-websocket to handle Yjs document collaboration
  2. A video streaming server to enable real-time video sharing between peers

Quick Start

Install dependencies

npm install

Start the unified WebSocket server

This repository implements a server that handles both Yjs document collaboration and video streaming in a single process. (source code)

Start the server:

node dist/server.cjs --port 3210

SSL/TLS Support (HTTPS/WSS)

For secure connections (required when your app is hosted on HTTPS), enable SSL/TLS:

# Enable SSL with auto-generated self-signed certificates
node dist/server.cjs --ssl --port 3210

# Or use custom certificates
node dist/server.cjs --ssl-key /path/to/private.key --ssl-cert /path/to/certificate.crt --port 3210

Important for HTTPS-hosted applications: Browsers enforce mixed content security policies that prevent HTTPS websites from connecting to non-secure WebSocket servers (ws://). You must use secure WebSocket connections (wss://) when your application is served over HTTPS.

The server exposes two WebSocket endpoints:

  • ws://hostname:port/ or wss://hostname:port/ - For Yjs document collaboration
  • ws://hostname:port/stream or wss://hostname:port/stream - For video streaming

Client Usage

For Yjs document collaboration:

import * as Y from 'yjs'
import { WebsocketProvider } from 'y-websocket'

const doc = new Y.Doc()
// Use wss:// for secure connections when your app is served over HTTPS
const wsProvider = new WebsocketProvider('wss://localhost:1234', 'my-roomname', doc)

wsProvider.on('status', event => {
  console.log(event.status) // logs "connected" or "disconnected"
})

For video streaming:

// Connect to the streaming endpoint
const ws = new WebSocket('ws://localhost:1234/stream')

// For stream source (sender)
ws.onopen = () => {
  // Register as a video source for a specific room
  ws.send(JSON.stringify({
    type: 'register-source',
    roomId: 'my-room-id'
  }))
  
  // Send video frames (example)
  function sendFrame(frameData) {
    ws.send(JSON.stringify({
      type: 'frame',
      data: frameData
    }))
  }
}

// For stream viewer (receiver)
ws.onopen = () => {
  // Join a specific room to receive video
  ws.send(JSON.stringify({
    type: 'join-room',
    roomId: 'my-room-id'
  }))
}

// Handle incoming messages
ws.onmessage = (event) => {
  const data = JSON.parse(event.data)
  
  if (data.type === 'source-available') {
    console.log('A video source is available in this room')
  } else if (data.type === 'frame') {
    // Handle incoming video frame
    displayFrame(data.data)
  }
}

Video Streaming Protocol

The streaming WebSocket endpoint relays MediaRecorder output (WebM/VP8[/Opus] chunks) from one source per room to all viewers in that room. Media chunks are sent as binary WebSocket messages; control messages are JSON text frames:

Message Types:

  1. Register as a stream source (station → server). Registration is last-writer-wins: a re-registration for the same room replaces the previous source and terminates its socket.

    {
      "type": "register-source",
      "roomId": "unique-room-identifier",
      "streamName": "Camera 1",
      "mimeType": "video/webm;codecs=\"vp8,opus\""
    }
  2. Join a room to receive video (viewer → server)

    {
      "type": "join-room",
      "roomId": "unique-room-identifier"
    }
  3. Source available (server → viewer, on join or registration). The viewer must create its MediaSource SourceBuffer with exactly this mimeType.

    {
      "type": "source-available",
      "roomId": "unique-room-identifier",
      "mimeType": "video/webm;codecs=\"vp8,opus\""
    }
  4. Viewer joined (server → source). The source restarts its MediaRecorder so the new viewer receives a fresh init segment at t=0.

    {
      "type": "viewer-joined",
      "roomId": "unique-room-identifier"
    }
  5. Source disconnected (server → viewers)

    {
      "type": "source-disconnected",
      "roomId": "unique-room-identifier"
    }

Configuration Options

Command Line Arguments

# Basic server options
node dist/server.cjs [options]

Options:
  --port=NUMBER        Port to listen on (default: 1234)
  --host=STRING        Host to bind to (default: 0.0.0.0)
  --help, -h          Show help message

# SSL/TLS options
  --ssl, --https      Enable HTTPS/WSS with self-signed certificates
  --ssl-key=PATH      Path to SSL private key file
  --ssl-cert=PATH     Path to SSL certificate file

Environment Variables

You can also configure the server using environment variables:

# Basic configuration
export PORT=3210
export HOST=0.0.0.0
export NODE_ENV=production

# SSL certificate paths
export SSL_KEY=/path/to/private.key
export SSL_CERT=/path/to/certificate.crt

# Start server
node dist/server.cjs

SSL/TLS Certificate Management

Self-Signed Certificates (Development)

For development and testing, the server can automatically generate self-signed certificates:

# Auto-generate self-signed certificates
node dist/server.cjs --ssl

Self-signed certificates will be saved in the ./certs/ directory and reused on subsequent starts.

Browser Security Warnings: Self-signed certificates will trigger security warnings in browsers. Users need to:

  1. Click "Advanced" when the security warning appears
  2. Click "Proceed to localhost" (or your domain)
  3. Accept the certificate risk

Standalone Executable

Pre-built standalone executables for Linux, macOS, and Windows are available on the GitHub Releases page. They include all dependencies and do not require Node.js on the target machine.

To build the executables yourself:

# Build for the current platform only
./build-sea.sh

# Build for all platforms (Linux x64, macOS x64, Windows x64)
./build-sea.sh --all

This produces three distribution folders:

Folder Platform Executable
edrys-executable-linux-x64/ Linux x64 edrys-server-linux-x64
edrys-executable-darwin-x64/ macOS x64 edrys-server-macos-x64
edrys-executable-win-x64/ Windows x64 edrys-server-win-x64.exe

Each folder also contains a ready-to-use startup script (start-server.sh / start-server.bat).

# Run directly (Linux/macOS)
cd edrys-executable-linux-x64
./edrys-server-linux-x64 --port 3210

# Or use the startup script
./start-server.sh

The standalone executable supports all the same command-line options as the Node.js version.

Note: The --ssl / --https flag requires OpenSSL to be installed on the target machine (used to generate self-signed certificates). On Linux install it with sudo apt-get install openssl, on macOS with brew install openssl. If you already have certificate files, you can skip this requirement by passing --ssl-key and --ssl-cert directly.

License

The MIT License © Kevin Jahns

Fork maintained by: edrys-labs

About

A basic backend for y-websocket with integrated video streaming

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages

  • JavaScript 97.0%
  • Shell 2.1%
  • Dockerfile 0.9%