添加 NoVNC 和 websokify 库
要添加 noVNC 库,请在命令行中执行以下命令:
$ npm i @novnc/novnc
然后转到websockify-js github 页面并将库下载为 zip 文件。我将它解压到我的项目根文件夹 /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
从这个位置执行这些命令来安装 websockify 依赖项:
$ cd websockify
$ npm install
现在我们可以运行 websockify 服务器:
$ ./websockify.js [options] SOURCE_ADDR:PORT TARGET_ADDR:PORT
例如,我将使用这些值运行命令,将websocket 流量从本地机器的端口5901(vnc 服务器默认端口)转发到端口6080:
$ ./websockify.js localhost:6080 localhost:5901
WebSocket settings:
- proxying from localhost:6080 to localhost:5901
- Running in unencrypted HTTP (ws://) mode
现在我们可以在package.json 中添加一个npm 脚本来启动websockify 服务器,转到脚本部分并添加以下行:
"websockify": "node tools/websockify-js/websockify/websockify.js"
这在package.json 中
{
"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"
},
.
.
.
所以我们可以使用以下命令从项目主文件夹启动websockify 服务器:
$ 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
如果你在linux上的 websockify Javascript 版本有问题,从这里下载 python 版本,解压后你可以用这个命令运行它:
$ ./run localhost:6080 localhost:5901
在 Angular 组件中实现 NoVNC
在这里,我们将在app.component 中实现 noVNC 。
在html 文件中添加一个div
以托管 Vnc 屏幕。
<div >
<div id="screen">
<!-- This is where the remote screen will appear -->
</div>
</div>
在app.component.ts如下所示:
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 },
});
}
}
之后,在另一个命令行中重新启动 angular 应用程序
$ ng serve
就是这样,您的 Vnc 客户端已启动并正在运行。
连接openstack
首先从openstack获取vnc url
[root@hcloud-controller ~]# openstack console url show instance-b
+-------+--------------------------------------------------------------------------------------------------+
| Field | Value |
+-------+--------------------------------------------------------------------------------------------------+
| type | novnc |
| url | http://hcloud-controller:6080/vnc_auto.html?path=%3Ftoken%3Dcbbe83a2-f8d3-4520-affb-321fe41fa0d0 |
+-------+--------------------------------------------------------------------------------------------------+
用这个url就可以直接访问vnc客户端, 需要将hcloud-controller 替换成openstack的ip地址。
我们也可以自己搭建客户端
这里我们就不需要用websockify进行代理
import { Component, OnInit } from '@angular/core';
// @ts-ignore
import RFB from '../../node_modules/@novnc/novnc/core/rfb.js';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent implements OnInit{
title = 'vnc-client';
// 直接用openstack生成的loken
url = 'ws://hcloud-controller:6080/?token=cbbe83a2-f8d3-4520-affb-321fe41fa0d0';
public rfb: RFB;
ngOnInit(): void {
this.startClient();
// @ts-ignore
window.rfb = this.rfb;
}
startClient(): void {
console.log('URL: ', this.url);
// Creating a new RFB object will start a new connection
this.rfb = new RFB(document.getElementById('screen'), this.url, {
credentials: {},
wsProtocols: ['binary'] //协议
});
}
}