This commit is contained in:
Baobhan Sith
2025-04-28 22:37:15 +08:00
parent eaf5711cc9
commit c3a2b63aef
3 changed files with 52 additions and 20 deletions
+28 -13
View File
@@ -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
});
@@ -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);
+15 -6
View File
@@ -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) => {