CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-simple-peer

Simple one-to-one WebRTC video/voice and data channels

Pending
Overview
Eval results
Files

info.mddocs/

Connection Information

Access connection details, statistics, peer addressing information, and real-time connection state monitoring for WebRTC peer connections.

Capabilities

Connection State Properties

Access real-time connection state and buffering information.

/**
 * Whether the peer connection and data channel are ready to use
 */
peer.connected: boolean;

/**
 * Amount of data buffered in the data channel (bytes)
 */
peer.bufferSize: number;

/**
 * Whether the peer has been destroyed and cleaned up
 */
peer.destroyed: boolean;

Usage Examples:

const peer = new Peer({ initiator: true });

// Check connection state
if (peer.connected) {
  peer.send('Hello!');
} else {
  console.log('Peer not connected yet');
}

// Monitor buffer size
function checkBuffer() {
  console.log('Buffer size:', peer.bufferSize, 'bytes');
  if (peer.bufferSize > 32768) { // 32KB
    console.warn('Buffer getting full - consider waiting');
  }
}

setInterval(checkBuffer, 1000);

// Check if peer is destroyed
if (peer.destroyed) {
  console.log('Peer has been destroyed');
} else {
  // Safe to use peer
  peer.send('Data');
}

Address Information

Access local and remote peer addressing details after connection establishment.

/**
 * Local peer's IP address (available after connection)
 */
peer.localAddress: string;

/**
 * Local peer's port number (available after connection)
 */
peer.localPort: number;

/**
 * Local peer's IP family ('IPv4' or 'IPv6')
 */
peer.localFamily: string;

/**
 * Remote peer's IP address (available after connection)  
 */
peer.remoteAddress: string;

/**
 * Remote peer's port number (available after connection)
 */
peer.remotePort: number;

/**
 * Remote peer's IP family ('IPv4' or 'IPv6')
 */
peer.remoteFamily: string;

/**
 * Get local address information as an object
 * @returns Address information object
 */
peer.address(): AddressInfo;

interface AddressInfo {
  address: string;
  family: string;
  port: number;
}

Usage Examples:

const peer = new Peer({ initiator: true });

peer.on('connect', () => {
  // Access address information
  console.log('Local address:', peer.localAddress, ':', peer.localPort);
  console.log('Local family:', peer.localFamily);
  console.log('Remote address:', peer.remoteAddress, ':', peer.remotePort);
  console.log('Remote family:', peer.remoteFamily);
  
  // Get structured address info
  const addressInfo = peer.address();
  console.log('Address info:', addressInfo);
  // { address: '192.168.1.100', family: 'IPv4', port: 54321 }
});

// Log connection details
function logConnectionInfo(peer) {
  console.log('Connection Info:');
  console.log('  Local:', `${peer.localFamily} ${peer.localAddress}:${peer.localPort}`);
  console.log('  Remote:', `${peer.remoteFamily} ${peer.remoteAddress}:${peer.remotePort}`);
  console.log('  Connected:', peer.connected);
  console.log('  Buffer size:', peer.bufferSize, 'bytes');
}

Connection Statistics

Retrieve detailed WebRTC connection statistics for monitoring and debugging.

/**
 * Get connection statistics
 * @param callback - Callback function receiving error and stats array
 */
peer.getStats(callback: (err: Error | null, stats: RTCStatsReport[]) => void): void;

interface RTCStatsReport {
  id: string;
  type: string;
  timestamp: number;
  [key: string]: any;
}

Usage Examples:

const peer = new Peer({ initiator: true });

peer.on('connect', () => {
  // Get basic stats
  peer.getStats((err, reports) => {
    if (err) {
      console.error('Failed to get stats:', err);
      return;
    }
    
    console.log('Stats reports:', reports.length);
    reports.forEach(report => {
      console.log('Report type:', report.type, 'ID:', report.id);
    });
  });
  
  // Monitor stats periodically
  setInterval(() => {
    peer.getStats((err, reports) => {
      if (err) return;
      
      // Find candidate pair stats
      const candidatePairs = reports.filter(r => r.type === 'candidate-pair');
      candidatePairs.forEach(pair => {
        if (pair.nominated) {
          console.log('Active connection:');
          console.log('  Bytes sent:', pair.bytesSent);
          console.log('  Bytes received:', pair.bytesReceived);
          console.log('  Round trip time:', pair.currentRoundTripTime, 'ms');
        }
      });
      
      // Find data channel stats
      const dataChannels = reports.filter(r => r.type === 'data-channel');
      dataChannels.forEach(dc => {
        console.log('Data channel:');
        console.log('  Messages sent:', dc.messagesSent);
        console.log('  Messages received:', dc.messagesReceived);
        console.log('  Bytes sent:', dc.bytesSent);
        console.log('  Bytes received:', dc.bytesReceived);
      });
    });
  }, 5000);
});

State Change Events

Monitor connection state changes and ICE gathering progress.

// ICE connection state changes
peer.on('iceStateChange', (iceConnectionState: string, iceGatheringState: string) => void);

// WebRTC signaling state changes  
peer.on('signalingStateChange', (signalingState: string) => void);

// ICE gathering timeout
peer.on('iceTimeout', () => void);

// Negotiation completed
peer.on('negotiated', () => void);

Usage Examples:

const peer = new Peer({ initiator: true });

// Monitor ICE state
peer.on('iceStateChange', (iceConnectionState, iceGatheringState) => {
  console.log('ICE Connection State:', iceConnectionState);
  console.log('ICE Gathering State:', iceGatheringState);
  
  switch (iceConnectionState) {
    case 'new':
      console.log('ICE connection starting');
      break;
    case 'checking':
      console.log('ICE connection checking connectivity');
      break;
    case 'connected':
      console.log('ICE connection established');
      break;
    case 'completed':
      console.log('ICE connection completed');
      break;
    case 'failed':
      console.log('ICE connection failed - check network/firewall');
      break;
    case 'disconnected':
      console.log('ICE connection temporarily disconnected');
      break;
    case 'closed':
      console.log('ICE connection closed');
      break;
  }
});

// Monitor signaling state
peer.on('signalingStateChange', signalingState => {
  console.log('Signaling State:', signalingState);
  
  switch (signalingState) {
    case 'stable':
      console.log('No ongoing exchange - ready for new negotiation');
      break;
    case 'have-local-offer':
      console.log('Local offer has been applied');
      break;
    case 'have-remote-offer':
      console.log('Remote offer has been applied');
      break;
    case 'have-local-pranswer':
      console.log('Local provisional answer applied');
      break;
    case 'have-remote-pranswer':
      console.log('Remote provisional answer applied');
      break;
    case 'closed':
      console.log('Connection closed');
      break;
  }
});

// Handle ICE timeout
peer.on('iceTimeout', () => {
  console.warn('ICE gathering timed out - connection may be slower');
});

// Handle negotiation completion
peer.on('negotiated', () => {
  console.log('Peer connection negotiation completed successfully');
});

Connection Monitoring Utilities

Utility functions for comprehensive connection monitoring and diagnostics.

Usage Examples:

// Comprehensive connection monitor
class PeerMonitor {
  constructor(peer) {
    this.peer = peer;
    this.startTime = Date.now();
    this.setupMonitoring();
  }
  
  setupMonitoring() {
    // Log all state changes
    this.peer.on('iceStateChange', (ice, gathering) => {
      console.log(`[${this.getElapsed()}] ICE: ${ice}, Gathering: ${gathering}`);
    });
    
    this.peer.on('signalingStateChange', state => {
      console.log(`[${this.getElapsed()}] Signaling: ${state}`);
    });
    
    this.peer.on('connect', () => {
      console.log(`[${this.getElapsed()}] Connected!`);
      this.logConnectionInfo();
      this.startStatsMonitoring();
    });
    
    this.peer.on('error', err => {
      console.error(`[${this.getElapsed()}] Error: ${err.code} - ${err.message}`);
    });
  }
  
  getElapsed() {
    return `${((Date.now() - this.startTime) / 1000).toFixed(1)}s`;
  }
  
  logConnectionInfo() {
    const peer = this.peer;
    console.log('Connection established:');
    console.log(`  Local: ${peer.localFamily} ${peer.localAddress}:${peer.localPort}`);
    console.log(`  Remote: ${peer.remoteFamily} ${peer.remoteAddress}:${peer.remotePort}`);
  }
  
  startStatsMonitoring() {
    this.statsInterval = setInterval(() => {
      this.peer.getStats((err, reports) => {
        if (err) return;
        
        const stats = this.extractKeyStats(reports);
        console.log(`[${this.getElapsed()}] Stats:`, stats);
      });
    }, 10000); // Every 10 seconds
  }
  
  extractKeyStats(reports) {
    const stats = {
      bytesSent: 0,
      bytesReceived: 0,
      messagesSent: 0,
      messagesReceived: 0,
      rtt: null
    };
    
    reports.forEach(report => {
      if (report.type === 'candidate-pair' && report.nominated) {
        stats.bytesSent += report.bytesSent || 0;
        stats.bytesReceived += report.bytesReceived || 0;
        stats.rtt = report.currentRoundTripTime;
      } else if (report.type === 'data-channel') {
        stats.messagesSent += report.messagesSent || 0;
        stats.messagesReceived += report.messagesReceived || 0;
      }
    });
    
    return stats;
  }
  
  destroy() {
    if (this.statsInterval) {
      clearInterval(this.statsInterval);
    }
  }
}

// Usage
const peer = new Peer({ initiator: true });
const monitor = new PeerMonitor(peer);

// Clean up when done
peer.on('close', () => {
  monitor.destroy();
});

WebRTC Support Detection

Check for WebRTC support before creating peer connections.

/**
 * Static property indicating WebRTC support in current environment
 */
Peer.WEBRTC_SUPPORT: boolean;

Usage Examples:

const Peer = require('simple-peer');

// Check support before creating peers
if (Peer.WEBRTC_SUPPORT) {
  console.log('WebRTC supported - creating peer');
  const peer = new Peer({ initiator: true });
} else {
  console.error('WebRTC not supported in this environment');
  // Fallback to alternative communication method
  fallbackToWebSocket();
}

// Environment-specific checks
function checkWebRTCCapabilities() {
  console.log('WebRTC Support:', Peer.WEBRTC_SUPPORT);
  
  if (typeof window !== 'undefined') {
    // Browser environment
    console.log('Browser WebRTC APIs:');
    console.log('  RTCPeerConnection:', !!window.RTCPeerConnection);
    console.log('  getUserMedia:', !!navigator.mediaDevices?.getUserMedia);
    console.log('  getDisplayMedia:', !!navigator.mediaDevices?.getDisplayMedia);
  } else {
    // Node.js environment
    console.log('Node.js environment - wrtc package required');
  }
}

Install with Tessl CLI

npx tessl i tessl/npm-simple-peer

docs

connection.md

data.md

index.md

info.md

media.md

tile.json