diff --git a/packages/backend/src/websocket.ts b/packages/backend/src/websocket.ts index 1a96967..5c5c846 100644 --- a/packages/backend/src/websocket.ts +++ b/packages/backend/src/websocket.ts @@ -503,10 +503,13 @@ export const initializeWebSocket = async (server: http.Server, sessionParser: Re // --- 消息转发: Client -> RDP --- ws.on('message', (message: RawData) => { if (rdpWs.readyState === WebSocket.OPEN) { - // console.log(`RDP Proxy (C->S): Forwarding message from ${ws.username}`); + // --- 添加中文日志 --- + const messageString = message.toString('utf-8'); // 尝试解码为 UTF-8 + console.log(`[RDP 代理 C->S] 用户: ${ws.username}, 会话: ${ws.sessionId}, 转发消息 (前 100 字符): ${messageString.substring(0, 100)}`); + // --- 结束日志 --- rdpWs.send(message); } else { - console.warn(`RDP Proxy (C->S): RDP WS not open, dropping message from ${ws.username}`); + console.warn(`[RDP 代理 C->S] 用户: ${ws.username}, 会话: ${ws.sessionId}, RDP WS 未打开,丢弃消息。`); } }); @@ -515,27 +518,33 @@ export const initializeWebSocket = async (server: http.Server, sessionParser: Re if (ws.readyState === WebSocket.OPEN) { // 将 RawData (可能是 Buffer) 转换为 UTF-8 字符串再发送 const messageString = message.toString('utf-8'); - // console.log(`RDP Proxy (S->C): Forwarding message to ${ws.username}: ${messageString.substring(0, 50)}...`); + // --- 添加中文日志 --- + console.log(`[RDP 代理 S->C] 用户: ${ws.username}, 会话: ${ws.sessionId}, 转发消息 (前 100 字符): ${messageString.substring(0, 100)}`); + // --- 结束日志 --- ws.send(messageString); } else { - console.warn(`RDP Proxy (S->C): Client WS not open, dropping message for ${ws.username}`); + console.warn(`[RDP 代理 S->C] 用户: ${ws.username}, 会话: ${ws.sessionId}, 客户端 WS 未打开,丢弃消息。`); } }); // --- 错误处理 --- ws.on('error', (error) => { - console.error(`WebSocket: RDP Proxy Client WS Error for ${ws.username}:`, error); + // --- 添加中文日志 --- + console.error(`[RDP 代理 客户端 WS 错误] 用户: ${ws.username}, 会话: ${ws.sessionId}, 错误:`, error); + // --- 结束日志 --- if (!rdpWsClosed && rdpWs.readyState !== WebSocket.CLOSED && rdpWs.readyState !== WebSocket.CLOSING) { - console.log(`WebSocket: RDP Proxy closing RDP WS due to client WS error.`); + console.log(`[RDP 代理] 因客户端 WS 错误关闭 RDP WS。会话: ${ws.sessionId}`); rdpWs.close(1011, 'Client WS Error'); rdpWsClosed = true; } clientWsClosed = true; }); rdpWs.on('error', (error) => { - console.error(`WebSocket: RDP Proxy RDP WS Error for ${ws.username}:`, error); + // --- 添加中文日志 --- + console.error(`[RDP 代理 RDP WS 错误] 用户: ${ws.username}, 会话: ${ws.sessionId}, 连接到 ${rdpTargetUrl} 时出错:`, error); + // --- 结束日志 --- if (!clientWsClosed && ws.readyState !== WebSocket.CLOSED && ws.readyState !== WebSocket.CLOSING) { - console.log(`WebSocket: RDP Proxy closing Client WS due to RDP WS error.`); + console.log(`[RDP 代理] 因 RDP WS 错误关闭客户端 WS。会话: ${ws.sessionId}`); ws.close(1011, `RDP WS Error: ${error.message}`); clientWsClosed = true; } @@ -545,25 +554,31 @@ export const initializeWebSocket = async (server: http.Server, sessionParser: Re // --- 关闭处理 --- ws.on('close', (code, reason) => { clientWsClosed = true; - console.log(`WebSocket: RDP Proxy Client WS Closed for ${ws.username}. Code: ${code}, Reason: ${reason.toString()}`); + // --- 添加中文日志 --- + console.log(`[RDP 代理 客户端 WS 关闭] 用户: ${ws.username}, 会话: ${ws.sessionId}, 代码: ${code}, 原因: ${reason.toString()}`); + // --- 结束日志 --- if (!rdpWsClosed && rdpWs.readyState !== WebSocket.CLOSED && rdpWs.readyState !== WebSocket.CLOSING) { - console.log(`WebSocket: RDP Proxy closing RDP WS due to client WS close.`); + console.log(`[RDP 代理] 因客户端 WS 关闭而关闭 RDP WS。会话: ${ws.sessionId}`); rdpWs.close(1000, 'Client WS Closed'); rdpWsClosed = true; } }); rdpWs.on('close', (code, reason) => { rdpWsClosed = true; - console.log(`WebSocket: RDP Proxy RDP WS Closed for ${ws.username}. Code: ${code}, Reason: ${reason.toString()}`); + // --- 添加中文日志 --- + console.log(`[RDP 代理 RDP WS 关闭] 用户: ${ws.username}, 会话: ${ws.sessionId}, 到 ${rdpTargetUrl} 的连接已关闭。代码: ${code}, 原因: ${reason.toString()}`); + // --- 结束日志 --- if (!clientWsClosed && ws.readyState !== WebSocket.CLOSED && ws.readyState !== WebSocket.CLOSING) { - console.log(`WebSocket: RDP Proxy closing Client WS due to RDP WS close.`); + console.log(`[RDP 代理] 因 RDP WS 关闭而关闭客户端 WS。会话: ${ws.sessionId}`); ws.close(1000, 'RDP WS Closed'); clientWsClosed = true; } }); rdpWs.on('open', () => { - console.log(`WebSocket: RDP Proxy connection to ${rdpTargetUrl} established for ${ws.username}. Forwarding messages.`); + // --- 添加中文日志 --- + console.log(`[RDP 代理 RDP WS 打开] 用户: ${ws.username}, 会话: ${ws.sessionId}, 到 ${rdpTargetUrl} 的连接已建立。开始转发消息。`); + // --- 结束日志 --- // Do not send custom message, let Guacamole protocol flow directly }); diff --git a/packages/frontend/src/components/RemoteDesktopModal.vue b/packages/frontend/src/components/RemoteDesktopModal.vue index 104ebdf..fe309b4 100644 --- a/packages/frontend/src/components/RemoteDesktopModal.vue +++ b/packages/frontend/src/components/RemoteDesktopModal.vue @@ -96,7 +96,15 @@ const connectRdp = async () => { } // 使用确定的基础 URL 构建后端代理端点的 URL - const tunnelUrl = `${backendBaseUrl}/rdp-proxy?token=${encodeURIComponent(token)}&width=${widthToSend}&height=${heightToSend}&dpi=${dpiToSend}`; + // 确保参数正确拼接,没有多余字符 + const queryParams = new URLSearchParams({ + token: token, + width: String(widthToSend), + height: String(heightToSend), + dpi: String(dpiToSend) + }); + const tunnelUrl = `${backendBaseUrl}/rdp-proxy?${queryParams.toString()}`; // 使用 URLSearchParams 确保格式正确 + console.log(`[RDP 模态框] 连接到隧道: ${tunnelUrl}`); // 记录最终 URL // @ts-ignore const tunnel = new Guacamole.WebSocketTunnel(tunnelUrl); diff --git a/packages/rdp/src/server.ts b/packages/rdp/src/server.ts index 5427fdc..ee482b2 100644 --- a/packages/rdp/src/server.ts +++ b/packages/rdp/src/server.ts @@ -50,21 +50,29 @@ const clientOptions = { let guacServer: any; // Define guacServer here to make it accessible in gracefulShutdown try { + console.log(`[RDP 服务] 正在使用选项初始化 GuacamoleLite: WS 端口=${websocketOptions.port}, Guacd=${guacdOptions.host}:${guacdOptions.port}`); guacServer = new GuacamoleLite(websocketOptions, guacdOptions, clientOptions); + console.log(`[RDP 服务] GuacamoleLite 初始化成功。`); if (guacServer.on) { guacServer.on('error', (error: Error) => { - // Minimal error handling for reverted state + console.error(`[RDP 服务] GuacamoleLite 服务器错误:`, error); }); guacServer.on('connection', (client: any) => { - const clientId = client.id || 'unknown'; + // 注意:这里的 'client' 通常代表到 guacd 的连接,而不是直接的 WebSocket 连接。 + // guacamole-lite 库可能抽象了直接的 WebSocket 处理。 + // 我们主要记录与 guacd 交互的事件。 + const clientId = client.id || '未知客户端ID'; + console.log(`[RDP 服务] Guacd 连接事件触发。客户端 ID: ${clientId}`); + // 尝试记录更多信息,如果库提供的话 (可能需要查看 guacamole-lite 文档或源码) + // console.log(`[RDP 服务] 客户端连接参数 (如果可用):`, client.connection?.settings); if (client && typeof client.on === 'function') { client.on('disconnect', (reason: string) => { - // Minimal disconnect handling + console.log(`[RDP 服务] Guacd 连接断开。客户端 ID: ${clientId}, 原因: ${reason || '未知'}`); }); client.on('error', (err: Error) => { - // Minimal client error handling + console.error(`[RDP 服务] Guacd 客户端错误。客户端 ID: ${clientId}, 错误:`, err); }); client.on('message', (message: Buffer | string) => { @@ -77,6 +85,7 @@ try { }); } } catch (error) { + console.error(`[RDP 服务] 初始化 GuacamoleLite 失败:`, error); process.exit(1); } @@ -166,8 +175,8 @@ app.get('/api/get-token', (req: any, res: any) => { }); apiServer.listen(API_PORT, () => { - console.log(`RDP API server listening on port ${API_PORT}`); // Added startup log - console.log(`Guacamole WebSocket server expected to be running on port ${GUAC_WS_PORT}`); + console.log(`[RDP 服务] API 服务器正在监听端口 ${API_PORT}`); + console.log(`[RDP 服务] Guacamole WebSocket 服务器应在端口 ${GUAC_WS_PORT} 上运行 (由 GuacamoleLite 管理)`); }); const gracefulShutdown = (signal: string) => {