Skip to main content

Overview

GenosRTC is the internal P2P module powering GenosDB’s real-time capabilities. It’s exposed via db.room and provides WebRTC-based communication for:
  • Data Channels: Send any type of data between peers
  • Media Streams: Share audio/video directly
  • Peer Management: Track connections and latency
  • Cellular Mesh: Scale to massive peer counts
GenosRTC is automatically available when you enable rtc: true during database initialization. No separate import required.

Getting Started

import { gdb } from "genosdb"

const db = await gdb("my-db", { rtc: true })

// Access the room object
const room = db.room

console.log("P2P communication ready")

Peer Events

peer:join

Fires when a peer joins the room.
db.room.on("peer:join", (peerId) => {
  console.log(`Peer ${peerId} joined`)
  updatePeerList()
})

peer:leave

Fires when a peer disconnects.
db.room.on("peer:leave", (peerId) => {
  console.log(`Peer ${peerId} left`)
  removePeerFromUI(peerId)
})

stream:add

Fires when a peer sends a media stream.
db.room.on("stream:add", (stream, peerId, metadata) => {
  console.log(`Receiving stream from ${peerId}`)
  
  // Display in video element
  const video = document.createElement("video")
  video.srcObject = stream
  video.autoplay = true
  document.body.appendChild(video)
})

Data Channels

Create a Channel

const channel = db.room.channel("chat")
type
string
required
Channel identifier in UTF-8 (max 12 bytes)

Send Data

// Send to all peers
channel.send({ message: "Hello everyone!" })

// Send to specific peer
channel.send({ message: "Private message" }, "peer-123")

// Send to multiple peers
channel.send({ data: "update" }, ["peer-1", "peer-2", "peer-3"])

Receive Data

channel.on("message", (data, peerId) => {
  console.log(`From ${peerId}:`, data)
})

Examples

Chat Application

class P2PChat {
  constructor(db, username) {
    this.db = db
    this.username = username
    this.channel = db.room.channel("chat")
    
    this.setupListeners()
  }
  
  setupListeners() {
    // Listen for messages
    this.channel.on("message", (data, peerId) => {
      this.displayMessage(data.username, data.text)
    })
    
    // Track peers
    this.db.room.on("peer:join", (peerId) => {
      this.displaySystemMessage(`${peerId} joined`)
    })
    
    this.db.room.on("peer:leave", (peerId) => {
      this.displaySystemMessage(`${peerId} left`)
    })
  }
  
  sendMessage(text) {
    this.channel.send({
      username: this.username,
      text,
      timestamp: Date.now()
    })
    
    // Display locally
    this.displayMessage(this.username, text)
  }
  
  displayMessage(username, text) {
    const msg = document.createElement("div")
    msg.textContent = `${username}: ${text}`
    document.getElementById("messages").appendChild(msg)
  }
  
  displaySystemMessage(text) {
    const msg = document.createElement("div")
    msg.textContent = text
    msg.style.color = "gray"
    document.getElementById("messages").appendChild(msg)
  }
}

// Usage
const chat = new P2PChat(db, "Alice")
chat.sendMessage("Hello everyone!")

Cursor Sharing

const cursorChannel = db.room.channel("cursors")
const cursors = new Map()

// Send cursor position
window.addEventListener("mousemove", (e) => {
  cursorChannel.send({
    x: e.clientX,
    y: e.clientY
  })
})

// Receive and render other cursors
cursorChannel.on("message", (position, peerId) => {
  if (!cursors.has(peerId)) {
    const cursor = document.createElement("div")
    cursor.className = "remote-cursor"
    document.body.appendChild(cursor)
    cursors.set(peerId, cursor)
  }
  
  const cursor = cursors.get(peerId)
  cursor.style.left = position.x + "px"
  cursor.style.top = position.y + "px"
})

// Clean up when peer leaves
db.room.on("peer:leave", (peerId) => {
  const cursor = cursors.get(peerId)
  if (cursor) {
    cursor.remove()
    cursors.delete(peerId)
  }
})

Game State Synchronization

const gameChannel = db.room.channel("game-state")

class MultiplayerGame {
  constructor(db) {
    this.channel = db.room.channel("game")
    this.players = new Map()
    
    this.channel.on("message", (data, peerId) => {
      this.updatePlayer(peerId, data)
    })
  }
  
  updateLocalPlayer(x, y, action) {
    const state = { x, y, action, timestamp: Date.now() }
    
    // Send to all peers
    this.channel.send(state)
    
    // Update locally
    this.renderPlayer("local", state)
  }
  
  updatePlayer(peerId, state) {
    this.players.set(peerId, state)
    this.renderPlayer(peerId, state)
  }
  
  renderPlayer(id, state) {
    // Render player at position
    console.log(`Player ${id} at (${state.x}, ${state.y})`, state.action)
  }
}

Media Streaming

Send Webcam Stream

async function startWebcam() {
  try {
    const stream = await navigator.mediaDevices.getUserMedia({
      video: true,
      audio: true
    })
    
    // Display local preview
    const localVideo = document.getElementById("local-video")
    localVideo.srcObject = stream
    
    // Send to all peers
    db.room.addStream(stream)
    
    console.log("Streaming webcam")
  } catch (error) {
    console.error("Failed to access webcam:", error)
  }
}

Receive Streams

db.room.on("stream:add", (stream, peerId, metadata) => {
  console.log(`Stream from ${peerId}:`, metadata)
  
  // Create video element
  const video = document.createElement("video")
  video.srcObject = stream
  video.autoplay = true
  video.muted = false
  video.id = `video-${peerId}`
  
  document.getElementById("remote-videos").appendChild(video)
})

Stop Streaming

// Stop sending a stream
db.room.removeStream(localStream)

// Or stop all tracks
localStream.getTracks().forEach(track => track.stop())

Screen Sharing

async function shareScreen() {
  try {
    const stream = await navigator.mediaDevices.getDisplayMedia({
      video: true
    })
    
    db.room.addStream(stream, null, { type: "screen" })
    
    console.log("Sharing screen")
  } catch (error) {
    console.error("Screen sharing failed:", error)
  }
}

Peer Management

Get Connected Peers

const peers = db.room.getPeers()

console.log(`Connected to ${peers.size} peers`)

for (const [peerId, connection] of peers) {
  console.log(`Peer ${peerId}:`, connection.connectionState)
}

Measure Latency

const latency = await db.room.ping("peer-123")

console.log(`Latency to peer: ${latency}ms`)

Leave Room

db.room.leave()

console.log("Disconnected from all peers")

Cellular Mesh Network

For massive scalability (100+ peers), enable the Cellular Mesh overlay:
const db = await gdb("my-app", {
  rtc: {
    cells: true // Enable with defaults
  }
})

// Or with custom configuration
const db = await gdb("my-app", {
  rtc: {
    cells: {
      cellSize: "auto",
      bridgesPerEdge: 2,
      maxCellSize: 50,
      targetCells: 100,
      debug: false
    }
  }
})

Mesh API

const mesh = db.room.mesh

// Send to all peers across all cells
mesh.send({ type: "broadcast", message: "Hello mesh!" })

// Receive messages
mesh.on("message", (data, fromPeerId) => {
  console.log(`From ${fromPeerId}:`, data)
})

Mesh Events

// Your cell status
db.room.on("mesh:state", (state) => {
  console.log("Cell ID:", state.cellId)
  console.log("Is Bridge:", state.isBridge)
  console.log("Connected Bridges:", state.bridges)
  console.log("Cell Size:", state.cellSize)
})

// Remote peer states (for visualization)
db.room.on("mesh:peer-state", (data) => {
  console.log(`Peer ${data.id} in cell ${data.cell}`)
  updateNetworkVisualization(data)
})

Scalability Comparison

PeersStandard P2PCellular Mesh
1010 connections~10 connections
100100 connections~10 connections
1,000Impractical~100 connections
10,000Impossible~100 connections
When to Use Mesh: Enable cellular mesh for applications expecting 100+ simultaneous peers:
  • Massive multiplayer games
  • Large-scale collaboration
  • Virtual events
  • Live broadcasts with audience participation

Configuration

Custom Relays

const db = await gdb("my-db", {
  rtc: {
    relayUrls: [
      "wss://relay1.example.com",
      "wss://relay2.example.com"
    ]
  }
})

TURN Servers

const db = await gdb("my-db", {
  rtc: {
    turnConfig: [
      {
        urls: ["turn:turn.example.com:3478"],
        username: "user",
        credential: "pass"
      }
    ]
  }
})

Build docs developers (and LLMs) love