原理
浏览器不支持VNC,所以不能直接连接VNC,但是可以使用代理,使用noVNC(noVNC是一个 HTML5 VNC 客户端)通过WebSocket建立连接,而VNC Server不支持WebSocket,所以需要开启Websockify代理来做WebSocket和TCP Socket之间的转换。当浏览器访问时,会通过网络加载运行noVNC。
关于通信
VNC是基于TCP的通信,VNC server处理的始终是TCP的流,而浏览器和noVNC之间是在http基础上使用WebSocket交互,VNC server是无法处理WebSocket的流,所以引入了 websockify ,负责把WebSocket流转换为普通的TCP流,使VNC server正常工作。
传输原理
将远程计算机的桌面图像编码为Web图像格式,然后通过WebSockets或XHR(XMLHttpRequest)将图像数据传输到客户端浏览器。客户端浏览器将图像数据解码并显示在屏幕上,同时将用户的输入事件传输回远程计算机。noVNC支持多种加密和身份验证方法,以确保安全性。
执行命令
node D:\VNC\node_modules\websockify-js\websockify\websockify.js --web// 执行websockify.js并且启动一个websocket服务器
D:\VNC\node_modules\noVNC //找到对应入口文件,加载该目录下资源,运行noVNC
8000 // 启动服务端口为8000
localhost:5900 // 转发的VNC地址和端口
关键代码
- websockify.js
fs.exists(filename, function(exists) {
if(!exists) {
return http_error(response, 404, "404 Not Found");
}
if (fs.statSync(filename).isDirectory()) {
// filename += '/index.html';
filename += '/vnc.html';
}
fs.readFile(filename, "binary", function(err, file) {
if(err) {
return http_error(response, 500, err);
}
var headers = {};
var contentType = mime.contentType(path.extname(filename));
if (contentType !== false) {
headers['Content-Type'] = contentType;
}
response.writeHead(200, headers);
response.write(file, "binary");
response.end();
});
});
读入入口文件,并且将文件以二进制形式写入服务
- vnc.html
<div id="noVNC_container">
<!-- Note that Google Chrome on Android doesn't respect any of these,
html attributes which attempt to disable text suggestions on the
on-screen keyboard. Let's hope Chrome implements the ime-mode
style for example -->
<textarea id="noVNC_keyboardinput" autocapitalize="off"
autocomplete="off" spellcheck="false" tabindex="-1"></textarea>
</div>
在该节点下生成对应的画布
- ui.js
connect()方法中建立连接时,生成一个rbf的实例,rbf中有具体解转码为web端桌面的操作。
ui.js中封装了连接时的各个方法