一、创建spring项目
引入依赖
<!-- Main Guacamole library -->
<dependency>
<groupId>org.apache.guacamole</groupId>
<artifactId>guacamole-common</artifactId>
<version>1.5.2</version>
<scope>compile</scope>
</dependency>
<!-- Guacamole JavaScript library -->
<dependency>
<groupId>org.apache.guacamole</groupId>
<artifactId>guacamole-common-js</artifactId>
<version>1.5.2</version>
<type>zip</type>
<scope>runtime</scope>
</dependency>
二、创建http服务处理
import org.apache.guacamole.GuacamoleException;
import org.apache.guacamole.net.GuacamoleSocket;
import org.apache.guacamole.net.GuacamoleTunnel;
import org.apache.guacamole.net.InetGuacamoleSocket;
import org.apache.guacamole.net.SimpleGuacamoleTunnel;
import org.apache.guacamole.protocol.ConfiguredGuacamoleSocket;
import org.apache.guacamole.protocol.GuacamoleConfiguration;
import org.apache.guacamole.servlet.GuacamoleHTTPTunnelServlet;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
/**
* @author
* @program
* @description http远程桌面请求
* @packagename
* @date 2023-06-07 16:51
**/
@WebServlet(urlPatterns = "/tunnel")
public class TutorialGuacamoleTunnelServlet extends GuacamoleHTTPTunnelServlet {
/**
*
*/
private static final long serialVersionUID = -3224942386695394818L;
@Override
protected GuacamoleTunnel doConnect(HttpServletRequest request) throws GuacamoleException {
//guacamole server地址
String hostname = "";
//guacamole server端口
int port = 4822;
GuacamoleConfiguration configuration = new GuacamoleConfiguration();
// 远程连接协议
configuration.setProtocol("rdp");
configuration.setParameter("hostname", "");
configuration.setParameter("port", "3389");
configuration.setParameter("username", "");
configuration.setParameter("password", "");
configuration.setParameter("ignore-cert", "true");
GuacamoleSocket socket = new ConfiguredGuacamoleSocket(
new InetGuacamoleSocket(hostname, port),
configuration
);
GuacamoleTunnel tunnel = new SimpleGuacamoleTunnel(socket);
return tunnel;
}
}
三、将guacamole-common-js压缩包解压复制到vue,guacamole-common-js压缩包在依赖下载路径下找
在vue的index.html同目录下创建static目录 将解压的guacamole-common-js目录复制到该目录下
四、显示远程界面
<!--
* @Descripttion: 远程桌面
* @Author:
* @Date:
* @LastEditors:
* @LastEditTime:
-->
<template>
<div
class="remote-desktop"
style="height: calc(100vh - 130px); margin: 0px 16px 8px; overflow-x: auto"
>
<div id="display"></div>
</div>
</template>
<script>
export default {
props: {},
data() {
return {};
},
mounted: function () {
this.$nextTick(function () {
this.show();
});
},
methods: {
// 失活页面时
deactivated() {},
// 激活页面时
activated() {},
show() {
// Get display div from document
var display = document.getElementById("display");
// Instantiate client, using an HTTP tunnel for communications.
// tunnel
//访问地址 这里我做了转发 请按自己服务填写 如 http://192.168.6.14:8080/tunnel
var guac = new Guacamole.Client(
new Guacamole.HTTPTunnel("/guacamole/tunnel")
);
// Add client to display div
display.appendChild(guac.getDisplay().getElement());
// Error handler
guac.onerror = function (error) {
console.log(error);
};
// Connect
guac.connect();
// Disconnect on close
window.onunload = function () {
guac.disconnect();
};
// Mouse
var mouse = new Guacamole.Mouse(guac.getDisplay().getElement());
mouse.onmousedown =
mouse.onmouseup =
mouse.onmousemove =
function (mouseState) {
guac.sendMouseState(mouseState);
};
// Keyboard
var keyboard = new Guacamole.Keyboard(document);
keyboard.onkeydown = function (keysym) {
guac.sendKeyEvent(1, keysym);
};
keyboard.onkeyup = function (keysym) {
guac.sendKeyEvent(0, keysym);
};
},
},
};
</script>
<style>
#display{
z-index:999 ;
position: absolute;
}
</style>
五、http协议会导致一直有请求,建议使用webSocket。修改如下
import org.apache.guacamole.GuacamoleException;
import org.apache.guacamole.net.GuacamoleSocket;
import org.apache.guacamole.net.GuacamoleTunnel;
import org.apache.guacamole.net.InetGuacamoleSocket;
import org.apache.guacamole.net.SimpleGuacamoleTunnel;
import org.apache.guacamole.protocol.ConfiguredGuacamoleSocket;
import org.apache.guacamole.protocol.GuacamoleClientInformation;
import org.apache.guacamole.protocol.GuacamoleConfiguration;
import org.apache.guacamole.websocket.GuacamoleWebSocketTunnelEndpoint;
import org.springframework.stereotype.Component;
import javax.websocket.EndpointConfig;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;
/**
* @author
* @program
* @description WebSocket远程桌面请求
* @packagename
* @date 2023-06-08 09:18
**/
@ServerEndpoint(value = "/webSocket", subprotocols = "guacamole")
@Component
public class WebSocketTunnel extends GuacamoleWebSocketTunnelEndpoint {
private static String host;
private static int port;
@Value("${guacamole.host:127.0.0.1}")
public void setHost(String host) {
WebSocketTunnel.host = host;
}
@Value("${guacamole.port:4822}")
public void setPort(int port) {
WebSocketTunnel.port = port;
}
/**
* Returns a new tunnel for the given session. How this tunnel is created
* or retrieved is implementation-dependent.
*
* @param session The session associated with the active WebSocket
* connection.
* @param endpointConfig information associated with the instance of
* the endpoint created for handling this single connection.
* @return A connected tunnel, or null if no such tunnel exists.
* @throws GuacamoleException If an error occurs while retrieving the
* tunnel, or if access to the tunnel is denied.
*/
@Override
protected GuacamoleTunnel createTunnel(Session session, EndpointConfig endpointConfig) throws GuacamoleException {
System.out.println("sessionMap:" + session.getRequestParameterMap());
// 获取url的值
Integer height = Integer.valueOf(session.getRequestParameterMap().get("height").get(0));
Integer width = Integer.valueOf(session.getRequestParameterMap().get("width").get(0));
GuacamoleClientInformation information = new GuacamoleClientInformation();
information.setOptimalScreenHeight(height);
information.setOptimalScreenWidth(width);
//--------------------------windows远程桌面测试--------------------------
GuacamoleConfiguration configuration = new GuacamoleConfiguration();
configuration.setProtocol("rdp");
configuration.setParameter("hostname", "");
configuration.setParameter("port", "3389");
configuration.setParameter("username", "");
configuration.setParameter("password", "123456");
//忽略证书
configuration.setParameter("ignore-cert", "true");
//domain 域
//security 安全模式 any-任意 nla-网络级别认证 nla-ext-扩展网络级身份验证 tls-TLS加密 vmconnect-Hyper-V / VMConnect rdp-RDP加密
//disable-auth 禁用认证 true false
//显示设置
//color-depth 色彩深度 8-256色 16-低色(16位) 24-真彩(24位) 32-真彩(32位)
//width 宽
//height 高
//dpi 分辨率
//resize-method 缩放方法 display-update-显示更新 reconnect-重新连接
//read-only 只读 true false
//vnc 参考地址https://guacamole.apache.org/doc/gug/configuring-guacamole.html#vnc
//autoretry 在放弃并返回错误之前重试连接的次数
//显示设置
//color-depth 色彩深度 8-256色 16-低色(16位) 24-真彩(24位) 32-真彩(32位)
//swap-red-blue 交换红/蓝成分 true false
//cursor 光标 local-本地 remote-远程
//read-only 只读 true false
//force-lossless true false
//代理设置
//dest-host
//dest-port
//--------------------------windows远程桌面测试--------------------------
GuacamoleSocket socket = new ConfiguredGuacamoleSocket(
new InetGuacamoleSocket(host, port),
configuration,
information
);
GuacamoleTunnel tunnel = new SimpleGuacamoleTunnel(socket);
return tunnel;
}
}
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;
/**
* @author
* @program
* @description
* @packagename
* @date 2023-06-08 18:01
**/
@Configuration
public class WebSocketConfig {
@Bean
public ServerEndpointExporter serverEndpointExporter(){
return new ServerEndpointExporter();
}
}
vue修改如下
// Instantiate client, using an HTTP tunnel for communications.
// tunnel
// Instantiate client, using an HTTP tunnel for communications.
// tunnel
//访问地址 这里我做了转发 请按自己服务填写 如 http://192.168.6.14:8080/tunnel
//var guac = new Guacamole.Client(
// new Guacamole.HTTPTunnel("/guacamole/tunnel")
//);
var guac = new Guacamole.Client(
new Guacamole.WebSocketTunnel("ws://192.168.6.14:8088/guacamole/webSocket")
);
// 如果需要传参 在连接出编写
guac.connect("height=" +
display.clientHeight +
"&width=" +
display.clientWidth +
"&id=" +
this.record.id);
整体代码
<!--
* @Descripttion: 远程桌面
* @Author:
* @Date:
* @LastEditors:
* @LastEditTime:
-->
<template>
<div
class="remote-desktop"
style="height: calc(100vh - 130px); margin: 0px 16px 8px; overflow-x: auto"
>
<BasicBreadcrumb :data="breadcrumbData" @click="cancel" @back="cancel" />
<div
id="display"
style="height: calc(-194px + 100vh); width: calc(-280px + 100vw)"
>
<a-result status="warning" :title="resultTitle" v-if="showResult">
<template #extra>
<a-button key="console" type="primary" @click="cancel">
返回
</a-button>
</template>
</a-result>
</div>
</div>
</template>
<script>
export default {
props: {
menu: {},
btnItem: {},
record: {},
},
data() {
return {
guac: null,
showResult: false,
keyboard: null,
resultTitle: "",
breadcrumbData: [],
};
},
mounted: function () {
this.$nextTick(function () {
this.show();
});
},
destroyed: function () {
this.guac.disconnect();
this.keyboard.onkeydown = null;
this.keyboard.onkeyup = null;
},
methods: {
// 失活页面时
deactivated() {
if (this.keyboard != null) {
this.keyboard.onkeydown = null;
this.keyboard.onkeyup = null;
}
},
// 激活页面时
activated() {
var _this = this;
if (_this.keyboard != null) {
_this.keyboard.onkeydown = function (keysym) {
_this.guac.sendKeyEvent(1, keysym);
};
_this.keyboard.onkeyup = function (keysym) {
_this.guac.sendKeyEvent(0, keysym);
};
}
},
cancel() {
this.$emit("cancel");
},
show() {
// Get display div from document
var display = document.getElementById("display");
var _this = this;
// Instantiate client, using an HTTP tunnel for communications.
// tunnel
// 192.168.6.14:8080/tunnel
//var guac = new Guacamole.Client(
//new Guacamole.HTTPTunnel("/guacamole/tunnel")
//);
this.guac = new Guacamole.Client(
new Guacamole.WebSocketTunnel(
"/guacamole/webSocket"
)
);
// Add client to display div
display.appendChild(this.guac.getDisplay().getElement());
// Error handler message
this.guac.onerror = function (error) {
console.log(error);
_this.resultTitle = error.message;
_this.showResult = true;
};
// Connect
this.guac.connect("height=" +
display.clientHeight +
"&width=" +
display.clientWidth +
"&id=" +
this.record.id);
// Disconnect on close
window.onunload = function () {
_this.guac.disconnect();
};
this.guac.onstatechange = function (state) {
console.log(state);
if (state == 3) {
// Mouse
var mouse = new Guacamole.Mouse(_this.guac.getDisplay().getElement());
mouse.onmousedown =
mouse.onmouseup =
mouse.onmousemove =
function (mouseState) {
_this.guac.sendMouseState(mouseState);
};
// Keyboard
_this.keyboard = new Guacamole.Keyboard(document);
_this.keyboard.onkeydown = function (keysym) {
_this.guac.sendKeyEvent(1, keysym);
};
_this.keyboard.onkeyup = function (keysym) {
_this.guac.sendKeyEvent(0, keysym);
};
}
};
},
},
};
</script>
<style>
#display {
z-index: 999;
position: absolute;
}
</style>
连接vnc时 vnc服务修改配置 不然连接不上 原因未知