Introduction

This tutorial will share with you how to create a simple Vnc client using Angular. I assume that you are familiar with Angular, the command line, and that you are comfortable using npm. I’ll explain how to use noVNC and websockify librairies to achieve that.

We’ll start with creating a new Angular app, it will be very basic. Then we’ll add noVNC and websockify libraries.

In this tutorial, commands that you enter will start with the \$ prompt. The output will follow. Lines that start with # are comments that I’ve added to explain a point.

Creating the Angular app

First, let’s create a simple angular application using the cli

shell
Copied!
$ ng new vnc-client

To keep things simple we will not create a new component, we will use the app component.

In app.component.html add a basic button to start the Vnc client.

app.component.html
Copied!
<div style="text-align:center">
  <h1>
    Welcome to {{ title }}!
  </h1>

  <button type="submit" (click)="startClient()">Start Vnc Client</button>
</div>

Of course you can use any event to trigger the starting of the vnc, or you can handle it in the ngOnInit() function for example.

And in app.component.ts

app.component.ts
Copied!
export class AppComponent {
  title = "vnc-client";

  startClient() {
    console.log("Starting !!!");
  }
}

Adding NoVNC and websokify Librairies

To add the noVNC library, in command line execute this command:

shell
Copied!
$ npm i @novnc/novnc

it will install @novnc in node_modules folder and add this line "@novnc/novnc": "^1.1.0", in package.json

Then go to websockify-js github page and download the library as a zip file. I extracted it under my project root folder at /vnc-client/tools/websockify-js/.

➜  websockify-js
    ├── CHANGES.txt
    ├── LICENSE.txt
    ├── README.md
    ├── docs
    │   ├── LICENSE.GPL-3
    │   ├── LICENSE.LGPL-3
    │   ├── LICENSE.MPL-2.0
    │   ├── TODO
    │   ├── notes
    │   └── release.txt
    ├── include
    │   ├── VT100.js
    │   ├── keysym.js
    │   ├── util.js
    │   ├── websock.js
    │   ├── webutil.js
    │   ├── wsirc.js
    │   └── wstelnet.js
    ├── websockify
    │   ├── package.json
    │   └── websockify.js
    ├── wsirc.html
    └── wstelnet.html

From this location execute these commandes to install websockify dependencies:

shell
Copied!
$ cd websockify
$ npm install

Now we can run websockify server:

shell
Copied!
$ ./websockify.js [options] SOURCE_ADDR:PORT TARGET_ADDR:PORT

for example I will run the command with these values, to forward websocket trafic from the port 5901 (vnc server default port) of my local machine, to the port 6080 :

shell
Copied!
$ ./websockify.js localhost:6080 localhost:5901

WebSocket settings:
    - proxying from localhost:6080 to localhost:5901
    - Running in unencrypted HTTP (ws://) mode

Now we can add an npm script in package.json to launch the websockify server, go to scripts section and add this line:
"websockify": "node tools/websockify-js/websockify/websockify.js"

which gives us this in package.json

package.json
Copied!
{
  "name": "vnc-client",
  "version": "0.0.0",
  "scripts": {
    "ng": "ng",
    "start": "ng serve",
    "build": "ng build",
    "test": "ng test",
    "lint": "ng lint",
    "e2e": "ng e2e",
    "websockify": "node tools/websockify-js/websockify/websockify.js"
  },
  .
  .
  .

So we can launch the websockify server form the project home folder with this command:

shell
Copied!
$ npm run websockify localhost:6080 localhost:5901

> vnc-client@0.0.0 websockify ~/vnc-client
> node tools/websockify-js/websockify/websockify.js "localhost:6080" "localhost:5901"

WebSocket settings:
    - proxying from localhost:6080 to localhost:5901
    - Running in unencrypted HTTP (ws://) mode

In case you have a problem with the Javascript version of websockify on linux, download the python version from here, after extraction you can run it with this command:

shell
Copied!
$ ./run localhost:6080 localhost:5901

Implementing NoVNC in Angular component

Here we will implement noVNC in our app.component.
In the html file add a div to host the Vnc screen.

app.component.html
Copied!
<div >
    <div id="screen">
      <!-- This is where the remote screen will appear -->
    </div>
</div>

the app.component.ts looks like this:

app.component.ts
Copied!
import { Component } from "@angular/core";

import RFB from "../../node_modules/@novnc/novnc/core/rfb.js";

@Component({
  selector: "app-root",
  templateUrl: "./app.component.html",
  styleUrls: ["./app.component.css"],
})
export class AppComponent {
  title = "vnc-client";

  public rfb: RFB;

  startClient() {
    console.log("Starting !!!");

    // Read parameters specified in the URL query string
    // By default, use the host and port of server that served this file
    const host = window.location.hostname;
    const port = "6080";
    const password = "foobar"; // password of your vnc server
    const path = "websockify";
    // Build the websocket URL used to connect
    let url = "ws";

    if (window.location.protocol === "https:") {
      url = "wss";
    } else {
      url = "ws";
    }

    url += "://" + host;
    if (port) {
      url += ":" + port;
    }
    url += "/" + path;

    console.log("URL: ", url);

    // Creating a new RFB object will start a new connection
    this.rfb = new RFB(document.getElementById("screen"), url, {
      credentials: { password: password },
    });
  }
}

After that, restart the angular app in another command line

shell
Copied!
$ ng serve

And that’s it, your Vnc client is up and running.

Resources:

novnc documentation
websockify python documentation
websockify-js documentation

The project repo on Github