peerpigeon
Version: 
WebRTC-based peer-to-peer mesh networking library with intelligent routing and signaling server
293 lines (238 loc) ⢠9.35 kB
JavaScript
/**
 * Bootstrap Hub Example
 * 
 * This example demonstrates how to set up a network of hubs using bootstrap connections.
 * Hubs automatically connect to each other through the bootstrap hub(s) on port 3000.
 */
import { PeerPigeonServer } from '../server/index.js';
// Example 1: Create the primary bootstrap hub on port 3000
async function createBootstrapHub() {
    console.log('=== Creating Bootstrap Hub (Port 3000) ===\n');
    
    const bootstrapHub = new PeerPigeonServer({
        port: 3000,
        host: 'localhost',
        isHub: true,
        // No bootstrap hubs to connect to - this is the primary hub
        autoConnect: false
    });
    bootstrapHub.on('hubRegistered', ({ peerId, totalHubs }) => {
        console.log(`[Bootstrap] Hub registered: ${peerId.substring(0, 8)}... (Total: ${totalHubs})`);
    });
    bootstrapHub.on('peerConnected', ({ peerId }) => {
        console.log(`[Bootstrap] Peer connected: ${peerId.substring(0, 8)}...`);
    });
    await bootstrapHub.start();
    console.log('[Bootstrap] Hub ready and waiting for connections\n');
    return bootstrapHub;
}
// Example 2: Create a hub that connects to the bootstrap hub (default port 3000)
async function createSecondaryHub(port) {
    console.log(`\n=== Creating Secondary Hub (Port ${port}) ===\n`);
    
    const hub = new PeerPigeonServer({
        port,
        host: 'localhost',
        isHub: true,
        // Automatically connects to port 3000 if not specified
        autoConnect: true
    });
    hub.on('bootstrapConnected', ({ uri }) => {
        console.log(`[Hub ${port}] ā
 Connected to bootstrap hub: ${uri}`);
    });
    hub.on('bootstrapDisconnected', ({ uri, code, reason }) => {
        console.log(`[Hub ${port}] š Disconnected from ${uri}: ${code} - ${reason}`);
    });
    hub.on('hubDiscovered', ({ peerId, via }) => {
        console.log(`[Hub ${port}] š¢ Discovered hub ${peerId.substring(0, 8)}... via ${via}`);
    });
    hub.on('hubRegistered', ({ peerId, totalHubs }) => {
        console.log(`[Hub ${port}] Hub registered: ${peerId.substring(0, 8)}... (Total: ${totalHubs})`);
    });
    await hub.start();
    return hub;
}
// Example 3: Create a hub with custom bootstrap URIs
async function createHubWithCustomBootstrap(port, bootstrapUris) {
    console.log(`\n=== Creating Hub with Custom Bootstrap (Port ${port}) ===\n`);
    
    const hub = new PeerPigeonServer({
        port,
        host: 'localhost',
        isHub: true,
        bootstrapHubs: bootstrapUris, // Custom bootstrap hub URIs
        autoConnect: true,
        reconnectInterval: 3000, // Reconnect after 3 seconds
        maxReconnectAttempts: 5  // Try up to 5 times
    });
    hub.on('bootstrapConnected', ({ uri }) => {
        console.log(`[Hub ${port}] ā
 Connected to bootstrap hub: ${uri}`);
    });
    hub.on('bootstrapDisconnected', ({ uri }) => {
        console.log(`[Hub ${port}] š Lost connection to ${uri}, will retry...`);
    });
    hub.on('hubDiscovered', ({ peerId }) => {
        console.log(`[Hub ${port}] š¢ Discovered another hub: ${peerId.substring(0, 8)}...`);
    });
    await hub.start();
    return hub;
}
// Example 4: Display hub statistics with bootstrap info
async function displayBootstrapStats(server, name) {
    const stats = server.getStats();
    const hubStats = server.getHubStats();
    console.log(`\nš Statistics for ${name}:`);
    console.log(`  Port: ${stats.port}`);
    console.log(`  Hub Peer ID: ${stats.hubPeerId?.substring(0, 8)}...`);
    console.log(`  Total Connections: ${stats.connections}`);
    console.log(`  Registered Hubs: ${stats.hubs}`);
    console.log(`  Bootstrap Connections: ${stats.bootstrapHubs.connected}/${stats.bootstrapHubs.total}`);
    
    if (hubStats.bootstrapHubs.length > 0) {
        console.log(`  Bootstrap Hubs:`);
        hubStats.bootstrapHubs.forEach(hub => {
            const status = hub.connected ? 'ā
' : 'ā';
            console.log(`    ${status} ${hub.uri} (attempts: ${hub.attemptNumber})`);
        });
    }
}
// Example 5: Create a multi-hub network
async function createHubNetwork() {
    console.log('=== Creating Hub Network ===\n');
    // Start bootstrap hub on port 3000
    const bootstrap = await createBootstrapHub();
    // Wait a moment for bootstrap to be ready
    await new Promise(resolve => setTimeout(resolve, 1000));
    // Start secondary hubs that auto-connect to port 3000
    const hub1 = await createSecondaryHub(3001);
    const hub2 = await createSecondaryHub(3002);
    const hub3 = await createSecondaryHub(3003);
    // Wait for connections to establish
    await new Promise(resolve => setTimeout(resolve, 2000));
    // Display statistics
    await displayBootstrapStats(bootstrap, 'Bootstrap Hub (3000)');
    await displayBootstrapStats(hub1, 'Hub 1 (3001)');
    await displayBootstrapStats(hub2, 'Hub 2 (3002)');
    await displayBootstrapStats(hub3, 'Hub 3 (3003)');
    console.log('\n=== Hub Network Topology ===');
    console.log('Bootstrap Hub (3000)');
    console.log('    ā');
    console.log('    āāā Hub 1 (3001)');
    console.log('    āāā Hub 2 (3002)');
    console.log('    āāā Hub 3 (3003)');
    return { bootstrap, hub1, hub2, hub3 };
}
// Example 6: Multiple bootstrap hubs for redundancy
async function createRedundantHubNetwork() {
    console.log('\n\n=== Creating Redundant Hub Network ===\n');
    // Create two bootstrap hubs
    const bootstrap1 = new PeerPigeonServer({
        port: 3000,
        host: 'localhost',
        isHub: true,
        autoConnect: false
    });
    await bootstrap1.start();
    const bootstrap2 = new PeerPigeonServer({
        port: 3001,
        host: 'localhost',
        isHub: true,
        autoConnect: false
    });
    await bootstrap2.start();
    console.log('Bootstrap hubs started\n');
    // Create a hub that connects to BOTH bootstrap hubs
    const redundantHub = await createHubWithCustomBootstrap(3005, [
        'ws://localhost:3000',
        'ws://localhost:3001'
    ]);
    await new Promise(resolve => setTimeout(resolve, 2000));
    await displayBootstrapStats(redundantHub, 'Redundant Hub (3005)');
    console.log('\n=== Redundant Topology ===');
    console.log('Bootstrap Hub 1 (3000) āā Redundant Hub (3005)');
    console.log('Bootstrap Hub 2 (3001) āā Redundant Hub (3005)');
    return { bootstrap1, bootstrap2, redundantHub };
}
// Main execution
async function main() {
    console.log('āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā');
    console.log('ā   PeerPigeon Bootstrap Hub Example        ā');
    console.log('āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā\n');
    try {
        // Create hub network
        const network = await createHubNetwork();
        // Wait to observe the network
        console.log('\n\nNetwork running... (press Ctrl+C to stop)');
        
        // Optional: Create redundant network after a delay
        setTimeout(async () => {
            try {
                await createRedundantHubNetwork();
            } catch (error) {
                console.error('Error creating redundant network:', error);
            }
        }, 5000);
        // Keep running until interrupted
        process.on('SIGINT', async () => {
            console.log('\n\nš Shutting down hub network...');
            
            await network.bootstrap.stop();
            await network.hub1.stop();
            await network.hub2.stop();
            await network.hub3.stop();
            
            console.log('ā
 All hubs stopped');
            process.exit(0);
        });
    } catch (error) {
        console.error('ā Error:', error);
        process.exit(1);
    }
}
// Configuration examples
function printConfigurationExamples() {
    console.log('\n\n=== Configuration Examples ===\n');
    console.log('1. Bootstrap Hub (Primary):');
    console.log(`
const bootstrap = new PeerPigeonServer({
    port: 3000,
    isHub: true,
    autoConnect: false  // Don't connect to other hubs
});
    `);
    console.log('2. Secondary Hub (Auto-connect to port 3000):');
    console.log(`
const hub = new PeerPigeonServer({
    port: 3001,
    isHub: true,
    autoConnect: true  // Automatically connects to ws://localhost:3000
});
    `);
    console.log('3. Hub with Custom Bootstrap URIs:');
    console.log(`
const hub = new PeerPigeonServer({
    port: 3002,
    isHub: true,
    bootstrapHubs: [
        'ws://hub1.example.com:3000',
        'ws://hub2.example.com:3000'
    ],
    reconnectInterval: 5000,
    maxReconnectAttempts: 10
});
    `);
    console.log('4. Hub with Custom Peer ID:');
    console.log(`
const hub = new PeerPigeonServer({
    port: 3003,
    isHub: true,
    hubPeerId: 'a1b2c3d4e5f6789012345678901234567890abcd'
});
    `);
}
// Run if this is the main module
if (import.meta.url === `file://${process.argv[1]}`) {
    main().catch(console.error);
}
export {
    createBootstrapHub,
    createSecondaryHub,
    createHubWithCustomBootstrap,
    displayBootstrapStats,
    createHubNetwork,
    createRedundantHubNetwork,
    printConfigurationExamples
};