躺不平&卷不赢:春节期间手撕WebRDP

发表于 2023-01-26

兔年的春节期间,没有躺平,可能也没卷赢。

挤了些时间,通过查阅资料,手撕了一个WebRDP程序,将Windows远程桌面搬到了Web端。

预览

webrdp preview

背景

今年春节,由于还处于后疫情阶段,为了不对国家和社会造成负担,我们蜗居在北京过年。儿子在练琴,媳妇在看书,我也闲下来思考如果度过这个年。

由于最近工作上的接触,现在我对Windows所用的RDP协议以及在浏览器上做图像渲染这块的技术还不太了解,所以准备在过年期间把这块功课补一补。 本来计划在空闲时间把这事搞定,结果投入的精力越来越多,直到成功的在页面上渲染出Windows的页面为止。

由于目前比较常见的WebRDP技术,是使用Apache的Guacamole开源模块进行RDP的代理实现,但是由于在工作中发现该guacamole-1.4.0经常出现段错误,故而想直接使用FreeRDP来实现Windows的远程连接控制。

概览

webrdp preview

WebRDP的主要思路,步骤如下:

  1. 浏览器通过WebSocket协议,发送鼠标、键盘消息给GoWebRDP代理程序;
  2. GoWebRDP代理程序将鼠标、键盘消息通过RDP协议发送给Windows系统;
  3. Windows系统会将终端的页面以64x64的BitMap格式返回给GoWebRDP代理程序;
  4. GoWebRDP将BitMap转换成png格式,发送给浏览器端;
  5. 浏览器端使用canvas画布技术,将png图片按照指定的坐标画在画布上。

整个样板工程的源代码,可以点击这里 查看。源代码的开发语言选择了Golang + cgo,也是我目前比较熟悉的语言,前端代码整体都在static/index.html里,主要是jquery的操作,没有做美化相关的处理。

关键技术点

WebSocket

WebSocket是一种基于TCP的全双工通信的应用层协议,以HTTP协议开始,通过Upgrade头及101响应码来进行握手,并更换为WebSocket协议。

WebSocket可以使客户端及服务器之间通过简单的交互来建立一个长连接通道,通过消息(Message)来进行通信。

WebSocket的优势比较显然:

FreeRDP

FreeRDP是一个Remote Desktop Protocol(协议)的一个实现,遵循Apache开源协议,支持3D功能,并有较高刷新率,也支持RemoteFX,H264编解码,用户管理,音频以及外设重定向等功能。

GoWebRDP使用了CGO技术,链接了FreeRDP的动态库,使用FreeRDP的API来通过RDP协议对Windows服务器进行远程连接的控制。

FreeRDP的链接地址,点击传送门

Canvas

Canvas 是HTML5提供的一种新的标签,在浏览器上画出一个矩形区域作为画布,使用javascript语言在这块画布上进行各种绘画操作。Canvas是flash技术的完美替代。

Canvas的应用场景:

总结

网络上FreeRDP相关的资料非常少,FAQ的内容也不全,API手册非常垃圾。没办法就下载了guacamole-server的代码,把FreeRDP那部分扒出来学习一下使用方法。

另外在使用CGo+FreeRDP的过程中,也出现了多种SegmentFault错误,故而改为使用代码编译FreeRDP的方式,可以快速定位发生在FreeRDP中的段错误来进行代码排错。

功夫不负有心人,历时几个晚上,让windows的页面出现在浏览器上,内心还是蛮激动的;之后再添加键盘鼠标的信号处理的时候,就比较顺利了。

这个样板工程的搭建,挤占了所有的空闲时间,收获到是不小。后续还准备使用golang把RDP协议给实现一遍,完全脱离开FreeRDP软件。

春节期间看着其他同事发的技术文章,真是再感慨一句:躺不平,卷不赢

上一篇 监控Linux文件被进程篡改 下一篇 在X86设备上构建多CPU架构的容器