当前位置:   article > 正文

Apache Guacamole集成到spring boot、vue

apache guacamole

一、创建spring项目

引入依赖

  1. <!-- Main Guacamole library -->
  2. <dependency>
  3. <groupId>org.apache.guacamole</groupId>
  4. <artifactId>guacamole-common</artifactId>
  5. <version>1.5.2</version>
  6. <scope>compile</scope>
  7. </dependency>
  8. <!-- Guacamole JavaScript library -->
  9. <dependency>
  10. <groupId>org.apache.guacamole</groupId>
  11. <artifactId>guacamole-common-js</artifactId>
  12. <version>1.5.2</version>
  13. <type>zip</type>
  14. <scope>runtime</scope>
  15. </dependency>

二、创建http服务处理

  1. import org.apache.guacamole.GuacamoleException;
  2. import org.apache.guacamole.net.GuacamoleSocket;
  3. import org.apache.guacamole.net.GuacamoleTunnel;
  4. import org.apache.guacamole.net.InetGuacamoleSocket;
  5. import org.apache.guacamole.net.SimpleGuacamoleTunnel;
  6. import org.apache.guacamole.protocol.ConfiguredGuacamoleSocket;
  7. import org.apache.guacamole.protocol.GuacamoleConfiguration;
  8. import org.apache.guacamole.servlet.GuacamoleHTTPTunnelServlet;
  9. import javax.servlet.annotation.WebServlet;
  10. import javax.servlet.http.HttpServletRequest;
  11. /**
  12. * @author
  13. * @program
  14. * @description http远程桌面请求
  15. * @packagename
  16. * @date 2023-06-07 16:51
  17. **/
  18. @WebServlet(urlPatterns = "/tunnel")
  19. public class TutorialGuacamoleTunnelServlet extends GuacamoleHTTPTunnelServlet {
  20. /**
  21. *
  22. */
  23. private static final long serialVersionUID = -3224942386695394818L;
  24. @Override
  25. protected GuacamoleTunnel doConnect(HttpServletRequest request) throws GuacamoleException {
  26. //guacamole server地址
  27. String hostname = "";
  28. //guacamole server端口
  29. int port = 4822;
  30. GuacamoleConfiguration configuration = new GuacamoleConfiguration();
  31. // 远程连接协议
  32. configuration.setProtocol("rdp");
  33. configuration.setParameter("hostname", "");
  34. configuration.setParameter("port", "3389");
  35. configuration.setParameter("username", "");
  36. configuration.setParameter("password", "");
  37. configuration.setParameter("ignore-cert", "true");
  38. GuacamoleSocket socket = new ConfiguredGuacamoleSocket(
  39. new InetGuacamoleSocket(hostname, port),
  40. configuration
  41. );
  42. GuacamoleTunnel tunnel = new SimpleGuacamoleTunnel(socket);
  43. return tunnel;
  44. }
  45. }

三、将guacamole-common-js压缩包解压复制到vue,guacamole-common-js压缩包在依赖下载路径下找

在vue的index.html同目录下创建static目录 将解压的guacamole-common-js目录复制到该目录下

四、显示远程界面

  1. <!--
  2. * @Descripttion: 远程桌面
  3. * @Author:
  4. * @Date:
  5. * @LastEditors:
  6. * @LastEditTime:
  7. -->
  8. <template>
  9. <div
  10. class="remote-desktop"
  11. style="height: calc(100vh - 130px); margin: 0px 16px 8px; overflow-x: auto"
  12. >
  13. <div id="display"></div>
  14. </div>
  15. </template>
  16. <script>
  17. export default {
  18. props: {},
  19. data() {
  20. return {};
  21. },
  22. mounted: function () {
  23. this.$nextTick(function () {
  24. this.show();
  25. });
  26. },
  27. methods: {
  28. // 失活页面时
  29. deactivated() {},
  30. // 激活页面时
  31. activated() {},
  32. show() {
  33. // Get display div from document
  34. var display = document.getElementById("display");
  35. // Instantiate client, using an HTTP tunnel for communications.
  36. // tunnel
  37. //访问地址 这里我做了转发 请按自己服务填写 如 http://192.168.6.14:8080/tunnel
  38. var guac = new Guacamole.Client(
  39. new Guacamole.HTTPTunnel("/guacamole/tunnel")
  40. );
  41. // Add client to display div
  42. display.appendChild(guac.getDisplay().getElement());
  43. // Error handler
  44. guac.onerror = function (error) {
  45. console.log(error);
  46. };
  47. // Connect
  48. guac.connect();
  49. // Disconnect on close
  50. window.onunload = function () {
  51. guac.disconnect();
  52. };
  53. // Mouse
  54. var mouse = new Guacamole.Mouse(guac.getDisplay().getElement());
  55. mouse.onmousedown =
  56. mouse.onmouseup =
  57. mouse.onmousemove =
  58. function (mouseState) {
  59. guac.sendMouseState(mouseState);
  60. };
  61. // Keyboard
  62. var keyboard = new Guacamole.Keyboard(document);
  63. keyboard.onkeydown = function (keysym) {
  64. guac.sendKeyEvent(1, keysym);
  65. };
  66. keyboard.onkeyup = function (keysym) {
  67. guac.sendKeyEvent(0, keysym);
  68. };
  69. },
  70. },
  71. };
  72. </script>
  73. <style>
  74. #display{
  75. z-index:999 ;
  76. position: absolute;
  77. }
  78. </style>

五、http协议会导致一直有请求,建议使用webSocket。修改如下

  1. import org.apache.guacamole.GuacamoleException;
  2. import org.apache.guacamole.net.GuacamoleSocket;
  3. import org.apache.guacamole.net.GuacamoleTunnel;
  4. import org.apache.guacamole.net.InetGuacamoleSocket;
  5. import org.apache.guacamole.net.SimpleGuacamoleTunnel;
  6. import org.apache.guacamole.protocol.ConfiguredGuacamoleSocket;
  7. import org.apache.guacamole.protocol.GuacamoleClientInformation;
  8. import org.apache.guacamole.protocol.GuacamoleConfiguration;
  9. import org.apache.guacamole.websocket.GuacamoleWebSocketTunnelEndpoint;
  10. import org.springframework.stereotype.Component;
  11. import javax.websocket.EndpointConfig;
  12. import javax.websocket.Session;
  13. import javax.websocket.server.ServerEndpoint;
  14. /**
  15. * @author
  16. * @program
  17. * @description WebSocket远程桌面请求
  18. * @packagename
  19. * @date 2023-06-08 09:18
  20. **/
  21. @ServerEndpoint(value = "/webSocket", subprotocols = "guacamole")
  22. @Component
  23. public class WebSocketTunnel extends GuacamoleWebSocketTunnelEndpoint {
  24. private static String host;
  25. private static int port;
  26. @Value("${guacamole.host:127.0.0.1}")
  27. public void setHost(String host) {
  28. WebSocketTunnel.host = host;
  29. }
  30. @Value("${guacamole.port:4822}")
  31. public void setPort(int port) {
  32. WebSocketTunnel.port = port;
  33. }
  34. /**
  35. * Returns a new tunnel for the given session. How this tunnel is created
  36. * or retrieved is implementation-dependent.
  37. *
  38. * @param session The session associated with the active WebSocket
  39. * connection.
  40. * @param endpointConfig information associated with the instance of
  41. * the endpoint created for handling this single connection.
  42. * @return A connected tunnel, or null if no such tunnel exists.
  43. * @throws GuacamoleException If an error occurs while retrieving the
  44. * tunnel, or if access to the tunnel is denied.
  45. */
  46. @Override
  47. protected GuacamoleTunnel createTunnel(Session session, EndpointConfig endpointConfig) throws GuacamoleException {
  48. System.out.println("sessionMap:" + session.getRequestParameterMap());
  49. // 获取url的值
  50. Integer height = Integer.valueOf(session.getRequestParameterMap().get("height").get(0));
  51. Integer width = Integer.valueOf(session.getRequestParameterMap().get("width").get(0));
  52. GuacamoleClientInformation information = new GuacamoleClientInformation();
  53. information.setOptimalScreenHeight(height);
  54. information.setOptimalScreenWidth(width);
  55. //--------------------------windows远程桌面测试--------------------------
  56. GuacamoleConfiguration configuration = new GuacamoleConfiguration();
  57. configuration.setProtocol("rdp");
  58. configuration.setParameter("hostname", "");
  59. configuration.setParameter("port", "3389");
  60. configuration.setParameter("username", "");
  61. configuration.setParameter("password", "123456");
  62. //忽略证书
  63. configuration.setParameter("ignore-cert", "true");
  64. //domain 域
  65. //security 安全模式 any-任意 nla-网络级别认证 nla-ext-扩展网络级身份验证 tls-TLS加密 vmconnect-Hyper-V / VMConnect rdp-RDP加密
  66. //disable-auth 禁用认证 true false
  67. //显示设置
  68. //color-depth 色彩深度 8-256色 16-低色(16位) 24-真彩(24位) 32-真彩(32位)
  69. //width 宽
  70. //height 高
  71. //dpi 分辨率
  72. //resize-method 缩放方法 display-update-显示更新 reconnect-重新连接
  73. //read-only 只读 true false
  74. //vnc 参考地址https://guacamole.apache.org/doc/gug/configuring-guacamole.html#vnc
  75. //autoretry 在放弃并返回错误之前重试连接的次数
  76. //显示设置
  77. //color-depth 色彩深度 8-256色 16-低色(16位) 24-真彩(24位) 32-真彩(32位)
  78. //swap-red-blue 交换红/蓝成分 true false
  79. //cursor 光标 local-本地 remote-远程
  80. //read-only 只读 true false
  81. //force-lossless true false
  82. //代理设置
  83. //dest-host
  84. //dest-port
  85. //--------------------------windows远程桌面测试--------------------------
  86. GuacamoleSocket socket = new ConfiguredGuacamoleSocket(
  87. new InetGuacamoleSocket(host, port),
  88. configuration,
  89. information
  90. );
  91. GuacamoleTunnel tunnel = new SimpleGuacamoleTunnel(socket);
  92. return tunnel;
  93. }
  94. }
  1. import org.springframework.context.annotation.Bean;
  2. import org.springframework.context.annotation.Configuration;
  3. import org.springframework.web.socket.server.standard.ServerEndpointExporter;
  4. /**
  5. * @author
  6. * @program
  7. * @description
  8. * @packagename
  9. * @date 2023-06-08 18:01
  10. **/
  11. @Configuration
  12. public class WebSocketConfig {
  13. @Bean
  14. public ServerEndpointExporter serverEndpointExporter(){
  15. return new ServerEndpointExporter();
  16. }
  17. }

vue修改如下

  1. // Instantiate client, using an HTTP tunnel for communications.
  2. // tunnel
  3. // Instantiate client, using an HTTP tunnel for communications.
  4. // tunnel
  5. //访问地址 这里我做了转发 请按自己服务填写 如 http://192.168.6.14:8080/tunnel
  6. //var guac = new Guacamole.Client(
  7. // new Guacamole.HTTPTunnel("/guacamole/tunnel")
  8. //);
  9. var guac = new Guacamole.Client(
  10. new Guacamole.WebSocketTunnel("ws://192.168.6.14:8088/guacamole/webSocket")
  11. );
  12. // 如果需要传参 在连接出编写
  13. guac.connect("height=" +
  14. display.clientHeight +
  15. "&width=" +
  16. display.clientWidth +
  17. "&id=" +
  18. this.record.id);

整体代码

  1. <!--
  2. * @Descripttion: 远程桌面
  3. * @Author:
  4. * @Date:
  5. * @LastEditors:
  6. * @LastEditTime:
  7. -->
  8. <template>
  9. <div
  10. class="remote-desktop"
  11. style="height: calc(100vh - 130px); margin: 0px 16px 8px; overflow-x: auto"
  12. >
  13. <BasicBreadcrumb :data="breadcrumbData" @click="cancel" @back="cancel" />
  14. <div
  15. id="display"
  16. style="height: calc(-194px + 100vh); width: calc(-280px + 100vw)"
  17. >
  18. <a-result status="warning" :title="resultTitle" v-if="showResult">
  19. <template #extra>
  20. <a-button key="console" type="primary" @click="cancel">
  21. 返回
  22. </a-button>
  23. </template>
  24. </a-result>
  25. </div>
  26. </div>
  27. </template>
  28. <script>
  29. export default {
  30. props: {
  31. menu: {},
  32. btnItem: {},
  33. record: {},
  34. },
  35. data() {
  36. return {
  37. guac: null,
  38. showResult: false,
  39. keyboard: null,
  40. resultTitle: "",
  41. breadcrumbData: [],
  42. };
  43. },
  44. mounted: function () {
  45. this.$nextTick(function () {
  46. this.show();
  47. });
  48. },
  49. destroyed: function () {
  50. this.guac.disconnect();
  51. this.keyboard.onkeydown = null;
  52. this.keyboard.onkeyup = null;
  53. },
  54. methods: {
  55. // 失活页面时
  56. deactivated() {
  57. if (this.keyboard != null) {
  58. this.keyboard.onkeydown = null;
  59. this.keyboard.onkeyup = null;
  60. }
  61. },
  62. // 激活页面时
  63. activated() {
  64. var _this = this;
  65. if (_this.keyboard != null) {
  66. _this.keyboard.onkeydown = function (keysym) {
  67. _this.guac.sendKeyEvent(1, keysym);
  68. };
  69. _this.keyboard.onkeyup = function (keysym) {
  70. _this.guac.sendKeyEvent(0, keysym);
  71. };
  72. }
  73. },
  74. cancel() {
  75. this.$emit("cancel");
  76. },
  77. show() {
  78. // Get display div from document
  79. var display = document.getElementById("display");
  80. var _this = this;
  81. // Instantiate client, using an HTTP tunnel for communications.
  82. // tunnel
  83. // 192.168.6.14:8080/tunnel
  84. //var guac = new Guacamole.Client(
  85. //new Guacamole.HTTPTunnel("/guacamole/tunnel")
  86. //);
  87. this.guac = new Guacamole.Client(
  88. new Guacamole.WebSocketTunnel(
  89. "/guacamole/webSocket"
  90. )
  91. );
  92. // Add client to display div
  93. display.appendChild(this.guac.getDisplay().getElement());
  94. // Error handler message
  95. this.guac.onerror = function (error) {
  96. console.log(error);
  97. _this.resultTitle = error.message;
  98. _this.showResult = true;
  99. };
  100. // Connect
  101. this.guac.connect("height=" +
  102. display.clientHeight +
  103. "&width=" +
  104. display.clientWidth +
  105. "&id=" +
  106. this.record.id);
  107. // Disconnect on close
  108. window.onunload = function () {
  109. _this.guac.disconnect();
  110. };
  111. this.guac.onstatechange = function (state) {
  112. console.log(state);
  113. if (state == 3) {
  114. // Mouse
  115. var mouse = new Guacamole.Mouse(_this.guac.getDisplay().getElement());
  116. mouse.onmousedown =
  117. mouse.onmouseup =
  118. mouse.onmousemove =
  119. function (mouseState) {
  120. _this.guac.sendMouseState(mouseState);
  121. };
  122. // Keyboard
  123. _this.keyboard = new Guacamole.Keyboard(document);
  124. _this.keyboard.onkeydown = function (keysym) {
  125. _this.guac.sendKeyEvent(1, keysym);
  126. };
  127. _this.keyboard.onkeyup = function (keysym) {
  128. _this.guac.sendKeyEvent(0, keysym);
  129. };
  130. }
  131. };
  132. },
  133. },
  134. };
  135. </script>
  136. <style>
  137. #display {
  138. z-index: 999;
  139. position: absolute;
  140. }
  141. </style>

连接vnc时 vnc服务修改配置 不然连接不上 原因未知

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家自动化/article/detail/550729
推荐阅读
相关标签
  

闽ICP备14008679号