fix vnc bug
This commit is contained in:
parent
c80d175556
commit
8cd238d9aa
@ -1509,7 +1509,9 @@ export function renderApp(state: AppViewState) {
|
||||
"
|
||||
>
|
||||
<claw-computer-panel
|
||||
.enabled=${state.showClawComputer}
|
||||
.vncUrl=${state.settings.vncWsUrl}
|
||||
.vncTarget=${state.settings.vncTarget}
|
||||
.password=${state.settings.vncPassword}
|
||||
@close=${() => state.toggleClawComputer()}
|
||||
style="flex: 1; min-height: 0;"
|
||||
|
||||
@ -22,7 +22,8 @@ interface RFBInstance {
|
||||
|
||||
@customElement("claw-computer-panel")
|
||||
export class ClawComputerPanel extends LitElement {
|
||||
@property() vncUrl = "ws://localhost:8081";
|
||||
@property() vncUrl = "";
|
||||
@property() vncTarget = "";
|
||||
@property() password = "";
|
||||
|
||||
@state() status = "等待連接...";
|
||||
@ -33,6 +34,20 @@ export class ClawComputerPanel extends LitElement {
|
||||
private screenRef: Ref<HTMLDivElement> = createRef<HTMLDivElement>();
|
||||
private autoConnectAttempted = false;
|
||||
|
||||
@property({ type: Boolean }) enabled = false;
|
||||
|
||||
updated(changedProperties: Map<string, unknown>) {
|
||||
if (changedProperties.has("enabled")) {
|
||||
if (this.enabled) {
|
||||
if (!this.isConnected) {
|
||||
setTimeout(() => void this.connect(), 100);
|
||||
}
|
||||
} else {
|
||||
this.disconnect();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static styles = css`
|
||||
:host {
|
||||
display: block;
|
||||
@ -179,7 +194,25 @@ export class ClawComputerPanel extends LitElement {
|
||||
};
|
||||
|
||||
private connect = async () => {
|
||||
const url = this.vncUrl || "ws://localhost:8081";
|
||||
let url =
|
||||
this.vncUrl || `${location.protocol === "https:" ? "wss" : "ws"}://${location.host}/vnc`;
|
||||
|
||||
// Append target configuration if available
|
||||
if (this.vncTarget) {
|
||||
try {
|
||||
const urlObj = new URL(url);
|
||||
urlObj.searchParams.set("target", this.vncTarget);
|
||||
url = urlObj.toString();
|
||||
} catch {
|
||||
// Fallback for non-standard WebSocket URLs if URL parsing fails
|
||||
if (url.includes("?")) {
|
||||
url += `&target=${encodeURIComponent(this.vncTarget)}`;
|
||||
} else {
|
||||
url += `?target=${encodeURIComponent(this.vncTarget)}`;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (this.rfb) {
|
||||
this.rfb.disconnect();
|
||||
}
|
||||
@ -213,6 +246,12 @@ export class ClawComputerPanel extends LitElement {
|
||||
clipViewport: true,
|
||||
});
|
||||
|
||||
// @ts-ignore
|
||||
this.rfb.addEventListener("securityfailure", (e: CustomEvent) => {
|
||||
console.error("VNC security failure:", e.detail);
|
||||
this.status = `Security negotiation failed: ${e.detail.reason || "Unknown reason"}`;
|
||||
});
|
||||
|
||||
if (this.rfb) {
|
||||
this.rfb.scaleViewport = this.isFitted;
|
||||
}
|
||||
@ -271,8 +310,8 @@ export class ClawComputerPanel extends LitElement {
|
||||
firstUpdated() {
|
||||
window.addEventListener("resize", this.handleResize);
|
||||
|
||||
// Auto-connect if URL is configured
|
||||
if (this.vncUrl) {
|
||||
// Auto-connect if enabled and URL is configured
|
||||
if (this.enabled && this.vncUrl) {
|
||||
// Use setTimeout to ensure DOM is fully ready and to allow UI to render first
|
||||
setTimeout(() => {
|
||||
void this.connect();
|
||||
|
||||
@ -138,8 +138,11 @@ export function loadSettings(): UiSettings {
|
||||
navCollapsed: false,
|
||||
navWidth: 220,
|
||||
navGroupsCollapsed: {},
|
||||
vncWsUrl: "ws://localhost:8081",
|
||||
vncTarget: "10.75.171.25900",
|
||||
vncWsUrl:
|
||||
typeof location !== "undefined"
|
||||
? `${location.protocol === "https:" ? "wss" : "ws"}://${location.host}/vnc`
|
||||
: "ws://localhost:18789/vnc",
|
||||
vncTarget: "localhost:5900",
|
||||
};
|
||||
|
||||
try {
|
||||
|
||||
@ -347,7 +347,7 @@ export function renderOverview(props: OverviewProps) {
|
||||
const v = (e.target as HTMLInputElement).value;
|
||||
props.onSettingsChange({ ...props.settings, vncTarget: v });
|
||||
}}
|
||||
placeholder="10.75.171.25900"
|
||||
placeholder="localhost:5900"
|
||||
/>
|
||||
</label>
|
||||
<label class="field">
|
||||
|
||||
@ -3,8 +3,8 @@ 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 VNC_HOST = process.env.OPENCLAW_VNC_HOST || "localhost";
|
||||
const VNC_PORT = parseInt(process.env.OPENCLAW_VNC_PORT || "5900", 10);
|
||||
const WS_PATH = "/vnc";
|
||||
|
||||
export function vncProxyPlugin(): PluginOption {
|
||||
@ -21,10 +21,29 @@ export function vncProxyPlugin(): PluginOption {
|
||||
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}`);
|
||||
wss.on("connection", (ws, req) => {
|
||||
const url = new URL(req.url ?? "/", "http://localhost");
|
||||
const target = url.searchParams.get("target");
|
||||
|
||||
const tcpSocket = net.connect(VNC_PORT, VNC_HOST);
|
||||
let host = VNC_HOST;
|
||||
let port = VNC_PORT;
|
||||
|
||||
if (target) {
|
||||
if (target.includes(":")) {
|
||||
const parts = target.split(":");
|
||||
host = parts[0];
|
||||
const p = parseInt(parts[1], 10);
|
||||
if (!isNaN(p)) {
|
||||
port = p;
|
||||
}
|
||||
} else {
|
||||
host = target;
|
||||
}
|
||||
}
|
||||
|
||||
console.log(`[VNC Proxy] Client connected to ${WS_PATH}, forwarding to ${host}:${port}`);
|
||||
|
||||
const tcpSocket = net.connect(port, host);
|
||||
|
||||
tcpSocket.on("data", (data) => {
|
||||
if (ws.readyState === ws.OPEN) {
|
||||
@ -61,7 +80,8 @@ export function vncProxyPlugin(): PluginOption {
|
||||
|
||||
// Hook into Vite's HTTP server upgrade event
|
||||
server.httpServer?.on("upgrade", (req, socket, head) => {
|
||||
if (req.url === WS_PATH) {
|
||||
const url = new URL(req.url ?? "/", "http://localhost");
|
||||
if (url.pathname === WS_PATH) {
|
||||
wss.handleUpgrade(req, socket, head, (ws) => {
|
||||
wss.emit("connection", ws, req);
|
||||
});
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user