@@ -15,11 +15,12 @@
|
|||||||
"test": "node test/test-network.js"
|
"test": "node test/test-network.js"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"simple-peer": "^9.11.1",
|
"@koush/wrtc": "^0.5.3",
|
||||||
"ws": "^8.14.2",
|
"chalk": "^5.3.0",
|
||||||
"express": "^4.18.2",
|
"express": "^4.18.2",
|
||||||
|
"simple-peer": "^9.11.1",
|
||||||
"uuid": "^9.0.1",
|
"uuid": "^9.0.1",
|
||||||
"chalk": "^5.3.0"
|
"ws": "^8.14.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"nodemon": "^3.0.2"
|
"nodemon": "^3.0.2"
|
||||||
|
|||||||
114
src/ring-node.js
114
src/ring-node.js
@@ -172,7 +172,7 @@ export class RingNode extends EventEmitter {
|
|||||||
|
|
||||||
ws.on('error', reject);
|
ws.on('error', reject);
|
||||||
|
|
||||||
setTimeout(() => reject(new Error('Connection timeout')), 10000);
|
setTimeout(() => reject(new Error('Connection timeout')), 15000);
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(`Failed to connect to peer ${nodeId}:`, error);
|
console.error(`Failed to connect to peer ${nodeId}:`, error);
|
||||||
@@ -282,48 +282,102 @@ export class RingNode extends EventEmitter {
|
|||||||
try {
|
try {
|
||||||
console.log(chalk.yellow(`🔄 Attempting to join ring via ${bootstrapNode}`));
|
console.log(chalk.yellow(`🔄 Attempting to join ring via ${bootstrapNode}`));
|
||||||
|
|
||||||
const success = await this.connectToPeer('bootstrap', bootstrapNode);
|
return new Promise((resolve, reject) => {
|
||||||
if (success) {
|
const ws = new WebSocket(`ws://${bootstrapNode}`);
|
||||||
// Request to join the ring network
|
let timeoutId;
|
||||||
this.sendJoinRingRequest();
|
|
||||||
return true;
|
ws.on('open', () => {
|
||||||
}
|
console.log(chalk.cyan('🔗 Connected to bootstrap node, sending join request...'));
|
||||||
return false;
|
|
||||||
|
// 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) {
|
} catch (error) {
|
||||||
console.error('Failed to join ring:', error);
|
console.error('Failed to join ring:', error);
|
||||||
return false;
|
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) {
|
async handleJoinRingRequest(ws, payload) {
|
||||||
const { nodeId, port, isOracle } = payload;
|
const { nodeId, port, isOracle } = payload;
|
||||||
|
|
||||||
console.log(chalk.cyan(`🔗 New node ${nodeId.substring(0, 8)} wants to join the ring`));
|
console.log(chalk.cyan(`🔗 New node ${nodeId.substring(0, 8)} wants to join the ring`));
|
||||||
|
|
||||||
// Add to known nodes
|
try {
|
||||||
this.knownNodes.set(nodeId, { port, isOracle });
|
// Add to known nodes
|
||||||
|
this.knownNodes.set(nodeId, { port, isOracle });
|
||||||
|
|
||||||
if (isOracle) {
|
if (isOracle) {
|
||||||
this.oracleNodes.add(nodeId);
|
this.oracleNodes.add(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'
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find optimal position in rings for the new node
|
|
||||||
await this.integrateNewNode(nodeId);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async integrateNewNode(nodeId) {
|
async integrateNewNode(nodeId) {
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import SimplePeer from 'simple-peer';
|
import SimplePeer from 'simple-peer';
|
||||||
import { EventEmitter } from 'events';
|
import { EventEmitter } from 'events';
|
||||||
import { v4 as uuidv4 } from 'uuid';
|
import { v4 as uuidv4 } from 'uuid';
|
||||||
|
import wrtc from '@koush/wrtc';
|
||||||
|
|
||||||
export class WebRTCManager extends EventEmitter {
|
export class WebRTCManager extends EventEmitter {
|
||||||
constructor(nodeId) {
|
constructor(nodeId) {
|
||||||
@@ -20,6 +21,7 @@ export class WebRTCManager extends EventEmitter {
|
|||||||
const peer = new SimplePeer({
|
const peer = new SimplePeer({
|
||||||
initiator: isInitiator,
|
initiator: isInitiator,
|
||||||
trickle: false,
|
trickle: false,
|
||||||
|
wrtc: wrtc,
|
||||||
config: {
|
config: {
|
||||||
iceServers: [
|
iceServers: [
|
||||||
{ urls: 'stun:stun.l.google.com:19302' },
|
{ urls: 'stun:stun.l.google.com:19302' },
|
||||||
|
|||||||
Referencia en una nueva incidencia
Block a user