fix bug for vnc ws proxy

This commit is contained in:
赵一寰 2026-03-14 15:48:08 +08:00
parent 8b49050cb2
commit c80d175556
4 changed files with 77 additions and 34 deletions

View File

@ -21,9 +21,11 @@
"vite": "8.0.0"
},
"devDependencies": {
"@types/ws": "^8.18.1",
"@vitest/browser-playwright": "4.1.0",
"jsdom": "^28.1.0",
"playwright": "^1.58.2",
"vitest": "4.1.0"
"vitest": "4.1.0",
"ws": "^8.19.0"
}
}

View File

@ -1,33 +0,0 @@
import http from "http";
// server/proxy.ts
import { WebSocket, WebSocketServer } from "ws";
const PORT = 8081;
const TARGET_VNC = "ws://10.75.171.0:25900"; // ← 改成你的真實 VNC 位址
const server = http.createServer();
const wss = new WebSocketServer({ server });
wss.on("connection", (clientWs) => {
console.log("[Proxy] Client connected");
const targetWs = new WebSocket(TARGET_VNC);
targetWs.on("open", () => console.log("[Proxy] 已連線到真實 VNC"));
clientWs.on("message", (data) => targetWs.readyState === WebSocket.OPEN && targetWs.send(data));
targetWs.on("message", (data) => clientWs.readyState === WebSocket.OPEN && clientWs.send(data));
const cleanup = () => {
targetWs.close();
clientWs.close();
};
clientWs.on("close", cleanup);
targetWs.on("close", cleanup);
clientWs.on("error", cleanup);
targetWs.on("error", cleanup);
});
server.listen(PORT, () => {
console.log(`✅ noVNC Proxy 啟動成功 → ws://localhost:${PORT}`);
});

View File

@ -1,6 +1,7 @@
import path from "node:path";
import { fileURLToPath } from "node:url";
import { defineConfig } from "vite";
import { vncProxyPlugin } from "./vnc-proxy-plugin.ts";
const here = path.dirname(fileURLToPath(import.meta.url));
@ -40,6 +41,7 @@ export default defineConfig(() => {
strictPort: true,
},
plugins: [
vncProxyPlugin(),
{
name: "control-ui-dev-stubs",
configureServer(server) {

72
ui/vnc-proxy-plugin.ts Normal file
View File

@ -0,0 +1,72 @@
import * as net from "net";
import type { PluginOption } from "vite";
import { WebSocketServer, type RawData } from "ws";
// Use environment variables or hardcoded defaults from the external script
const VNC_HOST = process.env.OPENCLAW_VNC_HOST || "10.75.171.0";
const VNC_PORT = parseInt(process.env.OPENCLAW_VNC_PORT || "25900", 10);
const WS_PATH = "/vnc";
export function vncProxyPlugin(): PluginOption {
return {
name: "openclaw-vnc-proxy",
configureServer(server) {
// Create a WebSocket server that shares the Vite HTTP server
const wss = new WebSocketServer({
noServer: true,
path: WS_PATH,
perMessageDeflate: false,
});
console.log(`🚀 [Proxy] VNC WebSocket proxy injected at ${WS_PATH}`);
console.log(` Forwarding to: ${VNC_HOST}:${VNC_PORT}`);
wss.on("connection", (ws) => {
console.log(`[VNC Proxy] Client connected to ${WS_PATH}`);
const tcpSocket = net.connect(VNC_PORT, VNC_HOST);
tcpSocket.on("data", (data) => {
if (ws.readyState === ws.OPEN) {
ws.send(data);
}
});
ws.on("message", (data: RawData) => {
if (!tcpSocket.writable) {
return;
}
if (Buffer.isBuffer(data)) {
tcpSocket.write(data);
} else if (Array.isArray(data)) {
tcpSocket.write(Buffer.concat(data));
} else {
tcpSocket.write(Buffer.from(data));
}
});
ws.on("close", () => tcpSocket.end());
tcpSocket.on("close", () => ws.close());
tcpSocket.on("error", (e) => {
console.error("[VNC Proxy] TCP Error:", e.message);
ws.close();
});
ws.on("error", (e) => {
console.error("[VNC Proxy] WebSocket Error:", e.message);
tcpSocket.end();
});
});
// Hook into Vite's HTTP server upgrade event
server.httpServer?.on("upgrade", (req, socket, head) => {
if (req.url === WS_PATH) {
wss.handleUpgrade(req, socket, head, (ws) => {
wss.emit("connection", ws, req);
});
}
});
},
};
}