- Initialize git repository - Add comprehensive .gitignore (protects .env and secrets) - Fix package.json (correct main entry, add metadata) - Expand .env.example with all required variables and comments - Add README.md with architecture, setup, and commands - Clean up empty scaffolding directories (logs removed, agents/models marked) - Backup previous .env file locally This establishes a safe foundation before further development.
91 lines
No EOL
2.2 KiB
JavaScript
91 lines
No EOL
2.2 KiB
JavaScript
const WebSocket = require('ws');
|
|
const axios = require('axios');
|
|
require('dotenv').config();
|
|
|
|
const WS_URL = process.env.WS_URL;
|
|
|
|
if (!WS_URL) {
|
|
console.error('❌ WS_URL is not set in .env');
|
|
process.exit(1);
|
|
}
|
|
|
|
let ws = null;
|
|
let reconnectAttempts = 0;
|
|
const INITIAL_BACKOFF = 2000; // 2 seconds
|
|
|
|
function connect() {
|
|
console.log(`🔄 Connecting to ${WS_URL}...`);
|
|
|
|
ws = new WebSocket(WS_URL);
|
|
|
|
ws.on('open', () => {
|
|
console.log('✅ Remote Agent connected to NetAnalyzer');
|
|
reconnectAttempts = 0;
|
|
});
|
|
|
|
ws.on('message', async (data) => {
|
|
try {
|
|
const request = JSON.parse(data);
|
|
if (request.action !== 'proxyRequest') return;
|
|
|
|
console.log(`🔄 Proxying ${request.method || 'GET'} ${request.url}`);
|
|
|
|
const response = await axios({
|
|
method: request.method || 'GET',
|
|
url: request.url,
|
|
headers: request.headers || {},
|
|
auth: request.auth || undefined,
|
|
data: request.body || undefined,
|
|
timeout: 30000,
|
|
});
|
|
|
|
ws.send(JSON.stringify({
|
|
requestId: request.requestId,
|
|
status: response.status,
|
|
data: response.data,
|
|
headers: response.headers
|
|
}));
|
|
|
|
} catch (err) {
|
|
console.error('Proxy error:', err.message);
|
|
ws.send(JSON.stringify({
|
|
requestId: request.requestId,
|
|
error: err.message,
|
|
status: err.response?.status || 500,
|
|
data: err.response?.data || null
|
|
}));
|
|
}
|
|
});
|
|
|
|
ws.on('close', (code, reason) => {
|
|
console.log(`❌ Disconnected (code: ${code}). Reconnecting...`);
|
|
scheduleReconnect();
|
|
});
|
|
|
|
ws.on('error', (err) => {
|
|
console.error('WebSocket error:', err.message);
|
|
});
|
|
}
|
|
|
|
function scheduleReconnect() {
|
|
reconnectAttempts++;
|
|
|
|
// Exponential backoff, capped at 60 seconds
|
|
const backoff = Math.min(INITIAL_BACKOFF * Math.pow(1.5, reconnectAttempts - 1), 60000);
|
|
|
|
console.log(`⏳ Reconnecting in ${Math.round(backoff/1000)}s... (attempt ${reconnectAttempts})`);
|
|
|
|
setTimeout(() => {
|
|
connect();
|
|
}, backoff);
|
|
}
|
|
|
|
// Start initial connection
|
|
connect();
|
|
|
|
// Graceful shutdown
|
|
process.on('SIGINT', () => {
|
|
console.log('🛑 Shutting down remote agent...');
|
|
if (ws) ws.close();
|
|
process.exit(0);
|
|
}); |