mirror of
https://github.com/BigBodyCobain/Shadowbroker.git
synced 2026-04-23 11:06:07 +02:00
90c2e90e2c
- Parallelized startup (60s → 15s) via ThreadPoolExecutor - Adaptive polling engine with ETag caching (no more bbox interrupts) - useCallback optimization for interpolation functions - Sliding LAYERS/INTEL edge panels replace bulky Record Panel - Modular fetcher architecture (flights, geo, infrastructure, financial, earth_observation) - Stable entity IDs for GDELT & News popups (PR #63, credit @csysp) - Admin auth (X-Admin-Key), rate limiting (slowapi), auto-updater - Docker Swarm secrets support, env_check.py validation - 85+ vitest tests, CI pipeline, geoJSON builder extraction - Server-side viewport bbox filtering reduces payloads 80%+ Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Former-commit-id: f2883150b5bc78ebc139d89cc966a76f7d7c0408
75 lines
1.9 KiB
JavaScript
75 lines
1.9 KiB
JavaScript
const WebSocket = require('ws');
|
|
const readline = require('readline');
|
|
|
|
const args = process.argv.slice(2);
|
|
const API_KEY = args[0] || process.env.AIS_API_KEY;
|
|
|
|
if (!API_KEY) {
|
|
console.error("FATAL: AIS_API_KEY is not set. WebSocket proxy cannot start.");
|
|
process.exit(1);
|
|
}
|
|
|
|
// Start with global coverage, until frontend updates it
|
|
let currentBboxes = [[[-90, -180], [90, 180]]];
|
|
let activeWs = null;
|
|
|
|
function sendSub(ws) {
|
|
if (ws && ws.readyState === WebSocket.OPEN) {
|
|
const subMsg = {
|
|
APIKey: API_KEY,
|
|
BoundingBoxes: currentBboxes,
|
|
FilterMessageTypes: [
|
|
"PositionReport",
|
|
"ShipStaticData",
|
|
"StandardClassBPositionReport"
|
|
]
|
|
};
|
|
ws.send(JSON.stringify(subMsg));
|
|
}
|
|
}
|
|
|
|
// Listen for dynamic bounding box updates via stdin from Python orchestrator
|
|
const rl = readline.createInterface({
|
|
input: process.stdin,
|
|
output: process.stdout,
|
|
terminal: false
|
|
});
|
|
|
|
rl.on('line', (line) => {
|
|
try {
|
|
const cmd = JSON.parse(line);
|
|
if (cmd.type === "update_bbox" && cmd.bboxes) {
|
|
currentBboxes = cmd.bboxes;
|
|
if (activeWs) sendSub(activeWs); // Resend subscription (swap and replace)
|
|
}
|
|
} catch (e) {}
|
|
});
|
|
|
|
function connect() {
|
|
const ws = new WebSocket('wss://stream.aisstream.io/v0/stream');
|
|
activeWs = ws;
|
|
|
|
ws.on('open', () => {
|
|
sendSub(ws);
|
|
});
|
|
|
|
ws.on('message', (data) => {
|
|
try {
|
|
const parsed = JSON.parse(data);
|
|
console.log(JSON.stringify(parsed));
|
|
} catch (e) {}
|
|
});
|
|
|
|
ws.on('error', (err) => {
|
|
console.error("WebSocket Proxy Error:", err.message);
|
|
});
|
|
|
|
ws.on('close', () => {
|
|
activeWs = null;
|
|
console.error("WebSocket Proxy Closed. Reconnecting in 5s...");
|
|
setTimeout(connect, 5000);
|
|
});
|
|
}
|
|
|
|
connect();
|