什么是 Apache Guacamole?
Guacamole是一种HTML5 Web应用程序,可使用远程桌面协议(例如VNC或RDP)提供对桌面环境的访问。可使用HTTP或WebSocket通过基于JavaScript的隧道流式传输文本数据,以及一种客户端实现,该实现支持Guacamole协议,并与来自Windows的Guacamole协议流结合使用时可以呈现远程显示。提供了跨浏览器的鼠标和键盘事件,一个XML驱动的屏幕键盘以及具有硬件加速合成功能的同步嵌套层。
guacamole-common-js 是 Apache Guacamole 项目的一部分。Apache Guacamole 是一个无客户端的远程桌面网关,支持 VNC、RDP 和 SSH 协议。guacamole-common-js 是一个 JavaScript 库,提供了与 Guacamole 协议交互的客户端实现,通常用于在浏览器中实现远程桌面访问。
Guacamole 特点
- 无客户端:Guacamole允许从任何地方远程访问一个或多个桌面,而无需安装客户端,这意味着用户不需要在其设备上安装任何额外的软件,只需通过一个支持 HTML5 的浏览器即可访问远程桌面。
- 协议支持:Guacamole 支持多种协议,包括 VNC、RDP、SSH 等。
- 扩展性:通过插件和扩展,可以将 Guacamole 的功能扩展到支持特定的需求。
- 身份验证:支持多种身份验证机制,包括数据库、LDAP、OpenID 等。
Guacamole 的架构
组件划分:
-
Guacamole Client:这是一个基于 HTML5 的客户端,可以在任何支持现代浏览器的设备上运行。用户通过浏览器访问 Guacamole Client,从而与远程桌面交互。
-
Guacamole Server (guacd):这是 Guacamole 的核心代理组件。Guacd 处理与远程桌面的实际连接(如 RDP、VNC、SSH 等协议),并将这些连接转换为可以通过 WebSocket 协议传输的格式,以供 Guacamole Client 使用。
-
Guacamole Protocol:Guacamole 使用自己的协议来在 Guacamole Client 和 guacd 之间传输数据。这种协议设计为可以在高延迟和低带宽条件下高效工作。
-
Guacamole Web Application:这是一个用 Java 编写的应用程序,通常在一个支持 Java Servlet 的应用服务器(如 Tomcat)上运行。它负责用户身份验证、会话管理、连接配置等。
Guacamole是一个提供了基于HTML5 web应用程序的远程桌面代理服务器。通过使用Guacamole服务器,我们很轻松的在浏览器上远程访问Guacamole代理的主机,是一个无客户端远程桌面网关。支持标准协议,如VNC、RDP、SSH。称他为无客户端,是因为没有插件和客户端软件被要求。由于HTML5,一旦Guacamole 被安装到服务端,通过web 浏览器就可以访问你的桌面。
我们可以在浏览器访问Guacamole页面的时候,此时,浏览器会通过HTTP使用Guacamole协议与Guacamole 服务器中的Web服务器进行连接。Guacamole Web应用会从用户的请求中读取Guacamole协议,并将其转发给guacd(本地Guacamole代理)。Guacd根据web 应用转发过来的Guacamole协议来代替用户连接到远程桌面服务器。在Guacamole Web应用与guacd进行通信的时候,两者均不需要知道实际使用的远程桌面协议是什么,即协议不可知性。
Guacd guacd是Guacamole动态支持多种远程桌面协议(这里统称为客户端插件)和基于web连接远程桌面协议的核心. guacd是一个安装在Guacamole上后台运行的守护进程, 等待来自web的连接. guacd也不需要理解特定的远程桌面协议, 一旦客户端插件开始启动, 他和guacd独立运行, 并且拥有和web应用完全的同学权限.
Guacamole.Client常用方法
Guacamole.Client 是 Apache Guacamole 的 JavaScript 客户端库的一部分,它用于与 Guacamole 服务器进行通信和处理远程桌面的显示。在 Guacamole.Client 中,有许多方法可以用来管理连接、处理用户输入、绘制图像等。以下是一些常见的方法:
connect() - 连接到指定的 Guacamole 会话。
disconnect() - 断开当前的 Guacamole 会话。
sendSize() - 发送显示窗口的大小信息到服务器。
sendKeyEvent() - 发送键盘事件到服务器。
sendMouseState() - 发送鼠标状态到服务器。
getDisplay() - 获取显示对象,用于渲染远程内容。
getClipboard() - 获取剪贴板对象,用于处理剪贴板数据。
getAudio() - 获取音频对象,用于处理音频流。
getVideo() - 获取视频对象,用于处理视频流。
setChannelMask() - 设置要启用的通道掩码。
sendClipboard() - 发送剪贴板数据到服务器。
error() - 处理连接过程中出现的错误。
onstatechange() - 连接状态改变时的回调函数。
onclipboard() - 收到剪贴板数据时的回调函数。
onaudio() - 收到音频数据时的回调函数。
onvideo() - 收到视频数据时的回调函数。
onfile() - 收到文件传输时的回调函数。
onerror() - 发生错误时的回调函数。
getState() - 获取当前连接的状态。
setMimetype() - 设置数据通道的 MIME 类型。
使用步骤
- 安装库:使用 npm 安装,npm install guacamole-common-js
- 创建 WebSocket 连接:使用 WebSocketTunnel 类创建一个 WebSocket 连接到 Guacamole 服务器。
- 创建 Guacamole 客户端: 使用 Guacamole.Client 类创建一个 Guacamole 客户端实例。
- 处理用户输入:使用 Mouse 和 Keyboard 类处理用户的鼠标和键盘输入,通过 Guacamole.Mouse 和 Guacamole.Keyboard 来捕获和发送输入事件
- 设置显示容器:使用 getDisplay() 方法获取显示元素,将其添加到 DOM 中以显示远程桌面。
- 连接到远程桌面,guacClient.connect();
- 断开连接时,guacClient.disconnect();
参考代码
import guacamole from 'guacamole-common-js';
// 创建 WebSocket 连接,创建传输管道
const webSocketClient = new guacamole.WebSocketTunnel(
'ws://your-guacamole-server:8080/websocket-tunnel'
);
// WebSocket报错处理
webSocketClient.onerror = res => {};
// 状态改变
webSocketClient.onstatechange = state => {
switch (state) {
case 0:
message.success('连接中.......');
break;
case 1:
message.success('连接成功!');
callback && callback();
break;
case 2:
if (this.connectState === 0) {
message.error('连接失败!');
} else {
message.warning('连接断开!');
}
break;
}
};
// 创建 Guacamole 客户端
const guacClient = new guacamole.Client(webSocketClient);
/**
* 接受监听,这是一个事件处理器,专门用于处理文件传输事件。当 Guacamole 服务器发送文件时,这个函数会被调用。
* stream: 代表文件数据流的对象。它用于接收文件数据。
* mimetype: 文件的 MIME 类型,描述文件的类型和格式。
* */
guacClient.onfile = function (stream, mimetype, filename) {
//通知服务端,已经收到了stream,向服务器发送一个确认
stream.sendAck('OK', guacamole.Status.Code.SUCCESS);
//开始处理输入流
downloadFile(stream, mimetype, filename);
};
// 获取显示元素并添加到 DOM,获取显示画布
const display = guacClient.getDisplay().getElement();
document.getElementById('remote-desktop').appendChild(display);
// 连接到远程桌面
guacClient.connect();
// 处理鼠标输入
const mouse = new guacamole.Mouse(display);
mouse.onmousedown = mouse.onmouseup = mouse.onmousemove = mouseState => {
guacClient.sendMouseState(mouseState);
};
// 处理鼠标和键盘事件
window.onresize = () => {
client.sendSize(window.innerWidth, window.innerHeight);
};
// 处理键盘输入
const keyboard = new guacamole.Keyboard(document);
keyboard.onkeydown = keysym => {
guacClient.sendKeyEvent(1, keysym);
};
keyboard.onkeyup = keysym => {
guacClient.sendKeyEvent(0, keysym);
};
// 断开连接时清理
window.onunload = () => {
guacClient.disconnect();
};
使用 guacamole-common-js 创建和管理远程桌面连接通常涉及到 Guacamole 服务器端的配置和设置。客户端代码需要通过 WebSocket 与 Guacamole 服务器通信,通常由后端生成连接令牌以验证并授权连接。
参考文章
juejin.cn/post/684490… (Guacamole实战)