DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Related

  • PHP vs React
  • NEXT.JS 13: Be Dynamic Without Limits
  • Top React Libraries for Data-Driven Dashboard App Development
  • Selenium vs Cypress: Does Cypress Replace Selenium?

Trending

  • Architecting Zero-Trust AI Agents: How to Handle Data Safely
  • Rethinking Java CRUDs With Event Sourcing and CQRS Patterns
  • Implementing Observability in Distributed Systems Using OpenTelemetry
  • 5 Common Security Pitfalls in Serverless Architectures
  1. DZone
  2. Software Design and Architecture
  3. Integration
  4. How to Access Remote Desktops Using Apache Guacamole

How to Access Remote Desktops Using Apache Guacamole

This article is intended for readers who want to create a custom Guacamole Client using guacamole-common-js and establish connections to their remote servers.

By 
Gokul Ramakrishnan user avatar
Gokul Ramakrishnan
·
Nov. 11, 24 · Tutorial
Likes (9)
Comment
Save
Tweet
Share
7.3K Views

Join the DZone community and get the full member experience.

Join For Free

What Is Apache Guacamole?

Apache Guacamole is an open-source framework created by the Apache Foundation that provides an HTML5 application that acts as a remote desktop gateway to enable access to remote desktops via the RDP, SSH, and VNC protocols without the use of any other third-party software.

The Guacamole solution includes many individual components, such as libguac, guacamole-common, and guacamole-ext. While these projects are beyond the scope of this article, we'll hone in on guacamole-common-js within the Guacamole ecosystem.

What Is guacamole-common-js?

The Guacamole project provides a JavaScript API for interfacing with components designed to meet Guacamole specifications. The guacamole-common-js API offers a JavaScript implementation of a Guacamole Client and tunneling mechanisms to transfer protocol data from JavaScript to the server side of the application. The server side typically runs a machine with guacd or the Guacamole Daemon. The guacamole-common-js library provides mouse and keyboard abstraction objects to translate JavaScript mouse and keyboard events into data that Guacamole can easily digest.

Using guacamole-common-js to Create a Custom Guacamole Client

Prerequisites: Install guacamole-common-js via any package manager of your choice. In this example, we will use npm.

Shell
 
npm i guacamole-common-js


Step 1:  Create a Guacamole Tunnel

Creating a Guacamole Tunnel allows you to stream data effortlessly between the server and your client.

JavaScript
 
const Guacamole = require('guacamole-common-js')

let tunnel = new Guacamole.Tunnel("path/to/your/tunnel");


You can pass additional parameters to your server via the tunnel URL using query parameters. For example, your tunnel URL can look like path/to/your/tunnel?param1=value1&param2=value2.

Step 2: Use the Tunnel Object to Create a Guacamole Client

You can create a Guacamole Client object by passing the Tunnel object you just created to the Guacamole.Client constructor.

JavaScript
 
let guacClient = new Guacamole.Client(tunnel)


Step 3: Call the Connect Function to Establish the Connection

So, we have the Guacamole Tunnel instance and the Guacamole Client instance. These are all we need to establish a connection to our remote machine.

JavaScript
 
guacClient.connect()


Just one thing to remember: The Guacamole.Tunnel object passed into the Guacamole.Client constructor must not already be connected. This is because, internally, the guacClient.connect() method will call the tunnel.connect() method, and if the tunnel is already connected, this operation will fail. 

Now, the astute amongst you will find that you still don't see the contents of your remote machine on your client. That's because we're still missing one crucial step.

Step 4: Get the Guacamole Display and Attach It to the DOM

Once you have established the connection by calling guacClient.connect(), you can view the remote machine's display by attaching the Guacamole display (an HTMLDivElement) to the DOM. Let's see how we can do that.

Imagine you have an HTML page where you wish to show the display of your remote machine.

HTML
 
<html>  
  <body id="guacCanvas">
  </body>
</html>


Next, let's get the HTMLDivElement, which needs to be displayed to the user from the guacClient.

JavaScript
 
// Get the display element from the guacClient
let displayElement = guacClient.getDisplay().getElement(); 
// Get the element from the DOM and attach the displayElement to it
let guacCanvas = document.getElementById('guacCanvas'); 
// Attach the displayElement to the canvas
guacCanvas.appendChild(displayElement);


Et voila! You now see the contents of your remote machine on your DOM. But wait, something isn't right. Your keyboard input does nothing, and neither does your mouse. How do we address that?

Step 5: Configure Keyboard and Mouse Events

To configure keyboard and mouse events, you need to set up the input handlers provided by guacamole-common-js.

Let's first look at how we can configure mouse events.

JavaScript
 
let mouse = new Guacamole.Mouse(guacElement)

// Primarily you need to handle 3 events. onmousedown, onmouseup, onmousemove.
// The high level idea is to send the current state of the mouse to guacamole
// whenever the mouse moves, the mouse gets clicked or unclicked.
const sendMouseState = (mouseState) => {
	guacClient.sendMouseState(mouseState);
}

// Essentially sending mouse state for all the individual events
mouse.onmousedown = mouse.onmouseup = mouse.onmousemove = sendMouseState;


Keyboard configuration is even simpler because there are just two events that need to be configured.

JavaScript
 
let keyboard = new Guacamole.Keyboard(guacElement); 
// you need to pass in the HTMLElement here where you want the keyboard events to 
// be passed into Guacamole. For example, if you pass in the document object instead
// of guacElement, you'll send all the events in the entire DOM to Guacamole, which may
// or may not be something you want. If you don't have any other UI elements in your
// DOM, you should be fine sending document, but if you have other UI elements in addition
// to your guacCanvas, you'd be better off passing just the guacCanvas.


// You need to configure 2 events. onkeyup and onkeydown
 keyboard.onkeydown = (keysym: number) => {
    guacClient.sendKeyEvent(1, keysym); // Send keydown event to the remote server
  };

  keyboard.onkeyup = (keysym: number) => {
    guacClient.sendKeyEvent(0, keysym); // Send keyup event to the remote server
  };


Step 6: Configure Touch Events (Optional)

Optionally, you can also configure your client for touch inputs, but it will be translated to Guacamole.Mouse events.

JavaScript
 
let touch = new Guacamole.Touch(guacCanvas);

// You need to configure 3 events here ontouchstart, ontouchend, ontouchmove
touch.onmousedown = touch.onmouseup = touch.onmousemove = 
  (touchState) => guacClient.sendMouseState(touchState);

const handleTouchEvent = (event) => {
  event.preventDefault();
  let touchState = touch.getMouseState(event);
  guacClient.sendMouseState(touchState);
}

touch.ontouchstart = touch.ontouchend = touch.ontouchmove = handleTouchEvent;

As you can see, we're translating touch events into Guacamole mouse events, and this step is entirely optional. You need to configure touch events only if you intend to use your custom client on a touchscreen device.

Step 7: Disconnect From Your Remote Machine

Finally, we've reached the last step, which is disconnecting from your remote machine, and it is as simple as calling a method on your client.

JavaScript
 
guacClient.disconnect();


Conclusion

To summarize, Apache Guacamole is a powerful and versatile open-source framework that offers a seamless way to access remote desktops through the RDP, SSH, or VNC protocols. The guacamole-common-js library allows developers to create custom Guacamole clients that can interface with other Guacamole components like guacamole-common, guaclib, and guacamole-ext.

By following the steps outlined in this article, you can set up a basic custom guacamole client that can connect to your remote servers and handle keyboard, mouse, and touch events.

JavaScript Open source Apache Guacamole

Opinions expressed by DZone contributors are their own.

Related

  • PHP vs React
  • NEXT.JS 13: Be Dynamic Without Limits
  • Top React Libraries for Data-Driven Dashboard App Development
  • Selenium vs Cypress: Does Cypress Replace Selenium?

Partner Resources

×

Comments

The likes didn't load as expected. Please refresh the page and try again.

  • RSS
  • X
  • Facebook

ABOUT US

  • About DZone
  • Support and feedback
  • Community research

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 215
  • Nashville, TN 37211
  • [email protected]

Let's be friends:

  • RSS
  • X
  • Facebook