@@ -15,11 +15,12 @@
|
||||
"test": "node test/test-network.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"simple-peer": "^9.11.1",
|
||||
"ws": "^8.14.2",
|
||||
"@koush/wrtc": "^0.5.3",
|
||||
"chalk": "^5.3.0",
|
||||
"express": "^4.18.2",
|
||||
"simple-peer": "^9.11.1",
|
||||
"uuid": "^9.0.1",
|
||||
"chalk": "^5.3.0"
|
||||
"ws": "^8.14.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"nodemon": "^3.0.2"
|
||||
|
||||
116
src/ring-node.js
116
src/ring-node.js
@@ -172,7 +172,7 @@ export class RingNode extends EventEmitter {
|
||||
|
||||
ws.on('error', reject);
|
||||
|
||||
setTimeout(() => reject(new Error('Connection timeout')), 10000);
|
||||
setTimeout(() => reject(new Error('Connection timeout')), 15000);
|
||||
});
|
||||
} catch (error) {
|
||||
console.error(`Failed to connect to peer ${nodeId}:`, error);
|
||||
@@ -282,48 +282,102 @@ export class RingNode extends EventEmitter {
|
||||
try {
|
||||
console.log(chalk.yellow(`🔄 Attempting to join ring via ${bootstrapNode}`));
|
||||
|
||||
const success = await this.connectToPeer('bootstrap', bootstrapNode);
|
||||
if (success) {
|
||||
// Request to join the ring network
|
||||
this.sendJoinRingRequest();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return new Promise((resolve, reject) => {
|
||||
const ws = new WebSocket(`ws://${bootstrapNode}`);
|
||||
let timeoutId;
|
||||
|
||||
ws.on('open', () => {
|
||||
console.log(chalk.cyan('🔗 Connected to bootstrap node, sending join request...'));
|
||||
|
||||
// Send join ring request directly through WebSocket
|
||||
ws.send(JSON.stringify({
|
||||
type: 'join-ring',
|
||||
from: this.id,
|
||||
payload: {
|
||||
nodeId: this.id,
|
||||
port: this.port,
|
||||
isOracle: this.isOracle
|
||||
}
|
||||
}));
|
||||
});
|
||||
|
||||
ws.on('message', (data) => {
|
||||
try {
|
||||
const message = JSON.parse(data.toString());
|
||||
if (message.type === 'join-response') {
|
||||
if (message.success) {
|
||||
console.log(chalk.green('✅ Successfully joined the ring network!'));
|
||||
clearTimeout(timeoutId);
|
||||
ws.close();
|
||||
resolve(true);
|
||||
} else {
|
||||
console.log(chalk.red('❌ Join request was rejected'));
|
||||
clearTimeout(timeoutId);
|
||||
ws.close();
|
||||
resolve(false);
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error parsing join response:', error);
|
||||
}
|
||||
});
|
||||
|
||||
ws.on('error', (error) => {
|
||||
console.error('WebSocket error:', error);
|
||||
clearTimeout(timeoutId);
|
||||
reject(error);
|
||||
});
|
||||
|
||||
ws.on('close', () => {
|
||||
clearTimeout(timeoutId);
|
||||
});
|
||||
|
||||
// Set timeout for join process
|
||||
timeoutId = setTimeout(() => {
|
||||
ws.close();
|
||||
reject(new Error('Connection timeout'));
|
||||
}, 15000); // Increased timeout to 15 seconds
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('Failed to join ring:', error);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
sendJoinRingRequest() {
|
||||
const message = {
|
||||
id: uuidv4(),
|
||||
type: 'join-ring',
|
||||
from: this.id,
|
||||
payload: {
|
||||
nodeId: this.id,
|
||||
port: this.port,
|
||||
isOracle: this.isOracle
|
||||
}
|
||||
};
|
||||
|
||||
this.webrtc.broadcast(message);
|
||||
}
|
||||
|
||||
async handleJoinRingRequest(ws, payload) {
|
||||
const { nodeId, port, isOracle } = payload;
|
||||
|
||||
console.log(chalk.cyan(`🔗 New node ${nodeId.substring(0, 8)} wants to join the ring`));
|
||||
|
||||
// Add to known nodes
|
||||
this.knownNodes.set(nodeId, { port, isOracle });
|
||||
|
||||
if (isOracle) {
|
||||
this.oracleNodes.add(nodeId);
|
||||
}
|
||||
try {
|
||||
// Add to known nodes
|
||||
this.knownNodes.set(nodeId, { port, isOracle });
|
||||
|
||||
if (isOracle) {
|
||||
this.oracleNodes.add(nodeId);
|
||||
}
|
||||
|
||||
// Find optimal position in rings for the new node
|
||||
await this.integrateNewNode(nodeId);
|
||||
// Find optimal position in rings for the new node
|
||||
await this.integrateNewNode(nodeId);
|
||||
|
||||
// Send success response
|
||||
ws.send(JSON.stringify({
|
||||
type: 'join-response',
|
||||
success: true,
|
||||
message: 'Successfully integrated into ring network'
|
||||
}));
|
||||
|
||||
console.log(chalk.green(`✅ Node ${nodeId.substring(0, 8)} successfully joined the ring`));
|
||||
} catch (error) {
|
||||
console.error(`Error handling join request from ${nodeId}:`, error);
|
||||
|
||||
// Send failure response
|
||||
ws.send(JSON.stringify({
|
||||
type: 'join-response',
|
||||
success: false,
|
||||
message: 'Failed to integrate into ring network'
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
async integrateNewNode(nodeId) {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import SimplePeer from 'simple-peer';
|
||||
import { EventEmitter } from 'events';
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
import wrtc from '@koush/wrtc';
|
||||
|
||||
export class WebRTCManager extends EventEmitter {
|
||||
constructor(nodeId) {
|
||||
@@ -20,6 +21,7 @@ export class WebRTCManager extends EventEmitter {
|
||||
const peer = new SimplePeer({
|
||||
initiator: isInitiator,
|
||||
trickle: false,
|
||||
wrtc: wrtc,
|
||||
config: {
|
||||
iceServers: [
|
||||
{ urls: 'stun:stun.l.google.com:19302' },
|
||||
|
||||
Referencia en una nueva incidencia
Block a user