Files
ringnet/node.js
2025-06-14 00:46:35 +02:00

166 líneas
4.8 KiB
JavaScript

#!/usr/bin/env node
import { RingNode } from './src/ring-node.js';
import chalk from 'chalk';
const args = process.argv.slice(2);
const options = {};
// Parse command line arguments
for (let i = 0; i < args.length; i++) {
switch (args[i]) {
case '--port':
options.port = parseInt(args[++i]);
break;
case '--id':
options.id = args[++i];
break;
case '--bootstrap':
options.bootstrap = args[++i];
break;
case '--position':
options.ringPosition = parseInt(args[++i]);
break;
case '--help':
console.log(`
${chalk.blue('Ring Network Node')}
Usage: node node.js [options]
Options:
--port <port> Port to listen on (default: random)
--id <id> Node ID (default: auto-generated)
--bootstrap <addr> Bootstrap node address (host:port)
--position <pos> Initial ring position (default: 0)
--help Show this help message
Examples:
node node.js --port 8080
node node.js --port 8081 --bootstrap localhost:8080
node node.js --id mynode --port 8082 --bootstrap localhost:8080
`);
process.exit(0);
break;
}
}
console.log(chalk.green('🚀 Starting Ring Network Node...'));
const node = new RingNode(options);
// Handle graceful shutdown
process.on('SIGINT', async () => {
console.log(chalk.yellow('\n🛑 Received shutdown signal...'));
await node.destroy();
process.exit(0);
});
process.on('SIGTERM', async () => {
console.log(chalk.yellow('\n🛑 Received termination signal...'));
await node.destroy();
process.exit(0);
});
// Connect to bootstrap node if specified
if (options.bootstrap) {
console.log(chalk.cyan(`🔗 Connecting to bootstrap node: ${options.bootstrap}`));
setTimeout(async () => {
try {
const success = await node.joinRing(options.bootstrap);
if (success) {
console.log(chalk.green('✅ Successfully joined the ring network!'));
} else {
console.log(chalk.red('❌ Failed to join the ring network'));
}
} catch (error) {
console.error(chalk.red('Error joining network:'), error.message);
}
}, 2000);
}
// Set up event handlers for demonstration
node.on('peerConnected', (peerId) => {
console.log(chalk.blue(`👋 New peer connected: ${peerId.substring(0, 8)}`));
});
node.on('peerDisconnected', (peerId) => {
console.log(chalk.red(`👋 Peer disconnected: ${peerId.substring(0, 8)}`));
});
node.on('ringMessage', ({ from, payload }) => {
console.log(chalk.magenta(`📨 Ring message from ${from.substring(0, 8)}: ${JSON.stringify(payload)}`));
});
node.on('networkUpdate', ({ from, payload }) => {
console.log(chalk.cyan(`🔄 Network update from ${from.substring(0, 8)}`));
});
// Interactive commands
process.stdin.setEncoding('utf8');
process.stdin.on('readable', () => {
const chunk = process.stdin.read();
if (chunk !== null) {
const command = chunk.trim();
handleCommand(command);
}
});
function handleCommand(command) {
const [cmd, ...args] = command.split(' ');
switch (cmd) {
case 'send':
if (args.length > 0) {
const message = args.join(' ');
node.sendRingMessage({ type: 'chat', content: message });
console.log(chalk.green(`📤 Sent: ${message}`));
}
break;
case 'info':
const info = node.getNetworkInfo();
console.log(chalk.blue('\n📊 Network Info:'));
console.log(JSON.stringify(info, null, 2));
break;
case 'peers':
const peers = node.webrtc.getConnectedPeers();
console.log(chalk.blue(`\n👥 Connected Peers (${peers.length}):`));
peers.forEach(peer => {
console.log(` - ${peer.substring(0, 8)}...`);
});
break;
case 'help':
console.log(chalk.blue(`
📚 Available Commands:
send <message> - Send a message through the ring
info - Show network information
peers - List connected peers
help - Show this help
quit - Exit the node
`));
break;
case 'quit':
case 'exit':
console.log(chalk.yellow('👋 Goodbye!'));
process.exit(0);
break;
default:
if (command.length > 0) {
console.log(chalk.red(`❓ Unknown command: ${cmd}. Type 'help' for available commands.`));
}
}
}
console.log(chalk.blue(`
🔗 Ring Network Node Started!
Node ID: ${node.id.substring(0, 8)}...
Port: ${node.port}
Type 'help' for available commands.
`));