Files
2026-02-01 19:56:01 +01:00

75 lines
2.2 KiB
JavaScript
Executable File

const WebSocket = require("ws");
/**
* Forwards WebSocket messages between browser clients (/robot)
* and a target WebSocket server (behind a firewall).
*
* @param {WebSocket.Server} wssInput - Local WebSocket server for browser clients
* @param {string} targetUrl - URL of target WebSocket server, e.g. "wss://internal.local:8080"
*/
function setupCommandForwarding(wssInput, targetUrl) {
let targetSocket;
const clients = new Set();
function connectTarget() {
console.log(`🔌 Connecting to Driver target server: ${targetUrl}`);
targetSocket = new WebSocket(targetUrl, { rejectUnauthorized: false });
targetSocket.on("open", () => {
console.log("✅ Connected to Driver target server");
});
targetSocket.on("message", (msg) => {
const data = msg.toString();
console.log("⬅️ Message from Driver to Sim:", data, "→ clients:", clients.size);
// Broadcast to all connected browsers
for (const client of clients) {
if (client.readyState === WebSocket.OPEN) {
try {
client.send(data);
} catch (err) {
console.error("❌ Error sending to client:", err.message);
}
}
}
});
targetSocket.on("close", () => {
console.warn("⚠️ Target Driver connection closed. Reconnecting in 5s...");
setTimeout(connectTarget, 5000);
});
targetSocket.on("error", (err) => {
console.error("❌ Target Driver connection error:", err.message);
});
}
connectTarget();
// When a browser connects to /robot
wssInput.on("connection", (ws, req) => {
console.log("🤖 Browser connected:", req.socket.remoteAddress);
clients.add(ws);
ws.on("message", (msg) => {
const data = msg.toString();
console.log("➡️ From browser → target:", data);
if (targetSocket?.readyState === WebSocket.OPEN) {
targetSocket.send(data);
} else {
console.warn("⚠️ Target not connected. Message dropped.");
}
});
ws.on("close", () => {
clients.delete(ws);
console.log("🔌 Browser disconnected");
});
ws.on("error", (err) => {
console.error("❌ Browser socket error:", err.message);
});
});
}
module.exports = { setupCommandForwarding };