VNC使用心得

VNC使用心得

项目中有这样一项需求:服务器上主机上安装的有程序打开服务、三维演示程序,屏幕拓展到了幕墙大屏;水晶位于舞台一侧,演讲者需要通过服务器的服务打在主机上的程序,并实现演示操作。
要完成上述需求就需要用到一个功能:远程桌面控制。

VNC控件

远程桌面协议有三个:VNC/SPICE/RDP。下面的连接介绍了这三种协议的特点和区别。

https://blog.csdn.net/caoshangpa/article/details/75206195

由于都是windows系统,我首先接触了rdp协议。从网上直接找的轮子。但是打开demo测试了一下,效果不是很好,首先是鼠标有延迟,使用效果不好,更重要的是rdp只支持一个设备远程连接 而且远界面会出现锁屏,就是我把桌面远程到了水晶讲台,结果服务器主机锁屏了,幕墙也锁屏了就无法对观众进行演示。

https://blog.csdn.net/wochendaixin/article/details/78465095

这两点让我直接选择了VNC的控件。

VNC(Virtual Network Computing)是基于RFB(Remote Frame Buffer)协议进行通信的,是一个基于平台无关的简单显示协议的超级瘦客户系统。VNC最初有某个实验室开发出来,后来由RealVNC公司负责维护和更新。RealVNC公司自己开发了一套客户端/服务端程序和云服务,个人的云服务好像是免费。而且还封装了一套多种语言的SDK供开发者使用,但是收费。

开发包中提供了安卓、HTML、C#、python语言的服务端可客户端Demo。
我使用的是C#代码编写的WPF程序。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qgXtegKa-1589344465949)(https://i.imgur.com/CRi7mWX.png)]

WPF的vnc样例的项目如下:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IbBJ4kDu-1589344465956)(https://i.imgur.com/R7xmlZS.png)]

ConnectSettings.cs:连接字符类,主要字段有云连接地址、密码,tcp连接的账号密码等。这个类在程序初始化的时候用来进行服务端连接。

ConnectSettingsWindow.xaml是用来连接服务端的窗口页面。

MainWindow.xaml是显示服务端桌面的主窗体,页面上包含了是否批改、颜色、鼠标控制等按钮。点击“connect”后 vnc控件容器便会开始播放。

ViewerControl.cs是realvnc封装的winform播放控件,是播放画面的核心部分。

VncKeyMapper.cs将客户端的键盘对服务端的键盘进行映射。

VncWinformEventMap.cs 对上面的键盘映射进行注册,通过按键事件注册才能在客户端敲击某一个键的时候服务端有响应。

VncLibraryThread.cs:加载和初始化库文件、开启客户端和服务端的会话、RunLoop这个我不知道怎么解释,大概意思就是一直进行loop里的操作,直到外部改变loop的值

--------------------------撰写分割线------------------------------

VncLibraryThread.cs:

  1. 加载库文件
  2. 运行runloop(用来开启新会话或者终止连接)
  3. 停止库文件
  4. dispose线程

ConnectSettingsWindow:负责创建一个Viwer类
MainWindow:
开启连接:设定viwer会话设置,包括连接属性和注册OnConnect、OnDisconnect、OnNewStatus事件、绑定按键事件、在线程中开启一个会话
显示状态和信息、更改vnc的功能等

VncViewerSession:
给对象查看器Viwer设置回调函数:
ConnectionCallback:connected、disconnected、
FramebufferCallback(画面帧获取后触发)、ServerEventCallback(服务事件)AnnotationManagerCallback(注释事件)
AuthenticationCallback(权限事件)

使用tcp连接:
定义连接器tcpConnector开启连接

更细的我还没研究透。我只说下我是如何使用的,以及大致的逻辑过程

  1. MainWindow初始化。位置:MainWindow.cs

    VncLibraryThread.Start();//线程启动

  2. LoadLibrary加载库文件。位置:VncLibraryThread.cs

    LibraryInit()//库文件初始化。就是加载根目录下的lib文件夹,将win-x86文件夹里的几个文件包含到项目里。这个地方要是移植debug程序时候记得改一下路径。在初始化的时候注意,要去realvnc官网试用/购买企业版,获得一个附加码,没有附加码是不能加载库文件的。
    //if (!string.IsNullOrEmpty(DirectTcpAddOnCode))
    Library.EnableAddOn(DirectTcpAddOnCode);
    private const string DirectTcpAddOnCode = @“V7mU+pv3mWBpl/NfRad4HSp6/GI7aUhOoikI0eAGCrvM+RTepIZQNnEJQ7Tcn3sT
    WQtP3kE3G95jSKzLGX+U9sbac8kvZhJx5YMa2xUryPE0CwOfI3jJg3woprA2MB3b
    scIHvUWbDHAtpB7x3dfWXjQbidSkJkBSMl9Z/NvvPOFzdW2Ua9mvAT2eimqfY/YX
    3O8NKWNyzdk9xG7TqjVWpo2QexGrFgd81TAIDvPqh2sgrL+KW69s/96fmJKfqd6+
    u/kuEhxhQj4Xx8e0H0Pej6y/EYP5MnD+lcLzhw3wM2IrDUjGKPL81wgVxcbgUmDd
    Y1Qr4jSmvtr1F6bq54ZVLjao9ppaOkF8S6xW63dnOllUSs0BDsCvUyDvc4nY/Ii0
    ztQj2N1OLMka3ajTMHUdEDMzpITgkMB6lz57nIYejcThRXeLxEjnxEy/AAl3I49l
    Cor+T98MfnZa7iw3nMdM0hMrdAyDdOq63yByQ2iCNqSbBXaP6+tLO+ottLttf9TK
    STY29jWOC+5c1IseRVoxAd8ZiGeCEmzfa3e0OTnAZMBsPzdQS05dF/J3pFHhLrez
    eA5yD/EvMRhd2QHSQk8oz27ZyOujXo0SlgfkTdOY52gPYfjsVv70JTSQCb4FgNMX
    i9HByrnRMquQI1KRoy0QUHk0R8qbybD2JXMGsVEIfX4=”;

  3. RunLoop,线程开启新回话或者使线程等待以便于终止。

  4. 点Connect=>Direct Tcp connection,输入服务端ip和端口号,使用默认的5900.StartConnection()开启连接。位置:MainWindow.cs

    StartConnection();

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-s4i2z2rS-1589344465960)(https://i.imgur.com/mk3go4k.png)]
5. 设定viewerSession属性;设定按键事件VncWinformEventMap; 启动会话StartViewerSession; 位置:MainWindow.cs=> StartConnection()
viewerSession = new VncViewerSession
{
LocalCloudAddress = ConnectSettings.LocalCloudAddress,
LocalCloudPassword = ConnectSettings.LocalCloudPassword,
PeerCloudAddress = ConnectSettings.PeerCloudAddress,
TcpAddress = ConnectSettings.DirectTcpIpAddress,
TcpPort = ConnectSettings.DirectTcpPort,
UsingCloud = ConnectSettings.UsingCloud,
AnnotationEnabled = true,

                FrameBufferHandler = VncViewerControl,

                OnConnect = () => DisplayMessage("Connected"),
                OnDisconnect = (msg, flags) =>
                    Dispatcher.BeginInvoke(new Action(() => OnDisconnect(msg))),

                // Put status messages on the status-label
                OnNewStatus = (msg) => DisplayMessage(msg),

                CurrentCanvasSize = VncViewerControl.Size
            };

            EventMap = new VncWinformEventMap(viewerSession, VncViewerControl);

            // Give the viewer session user-input events
            if (KeyboardControl.IsChecked == true)
                EventMap.RegisterKeyboardControls(true);

            if (MouseControl.IsChecked == true)
                EventMap.RegisterMouseControls(true);

            ManageConnectControls(true);

            // Give the child-control the focus of keyboard
            VncViewerControl.Focus();

        VncLibraryThread.StartViewerSession(viewerSession);
        ViewerSession = viewerSession;
  1. 跳进Runloop开启一个新会话 范围:VncLibraryThread的RunLoop
    while (WaitHandle.WaitAny(handles) == 0) // NewSession
    {
    // Reset the event, so that the UI may start a new session
    // as soon as it is notified of this session’s disconnection.
    NewSession.Reset();

             //
             // Do all the work in here!
             //
             CurrentVncViewerSession.Run();
         }
    
  2. 设置回调函数、调整帧页面大小、连接服务器。连接了以后就会线程运行OnFrameBufferUpdated绘制GUI、控件绘制ViewerControl_Paint之类的。位置:ViewerSession.cs
    using (DirectTcpConnector tcpConnector = new DirectTcpConnector())
    {

                     tcpConnector.Connect(TcpAddress, TcpPort, connectionHandler);
                 }`
    
  3. 程序弹出一个回调页面,
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ogzjvMjk-1589344465967)(https://i.imgur.com/zy3YGaq.png)]如果ok不能点击,可以换个电脑试一下,我真不知道为什么在我的工作pc上不能用
    点击OK后会再回调一个输入账号密码的窗口,登录即可。
    这个页面可以重写。由于我只需要点击按钮直接登录服务器,因此我做了以下操作:
    1)设定对等验证回调函数(直译),并注册

    PeerVerificationCallback = new Viewer.PeerVerificationCallback(
           verifyPeer:(Viewer,hexFingerprint,catchphraseFingerprint,serverRsaPublic) => {
               Viewer.SendPeerVerificationResponse(true);//当出现OK/Cancel窗口时 直接选择ok;hexFingerprint是服务器签名,catchphraseFingerprint什么Catchphase信息、
           });
    

    viewer.SetPeerVerificationCallback(PeerVerificationCallback);

  1. 设定权限验证回调函数,并注册

    AuthenticationCallback = new Viewer.AuthenticationCallback(
    requestUserCredentials:(Viewer, needUser, needPasswd) => {
    Viewer.SendAuthenticationResponse(true, null,“123456”); //发送账号密码, 是否需要账号密码跟realvnc服务端的设置有关。我设置的是只要vnc密码
    });
    viewer.SetAuthenticationCallback(AuthenticationCallback);

  1. 完成,实现远程桌面。
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xHeHY9uA-1589344465972)(https://i.imgur.com/BtryDpC.png)]
    其他的就是退出之类的,无非是注销、回收等操作。

我最开始学习realvnc是想着服务端有现成的realvncserver(自己找序列号破一下),做的相当好,sdk也是他们封装好的,简单方便效果好。但是我做好之后 跟领导一说 要55欧元一年,领导说再研究下开源的vnc控件吧。我一个同事说 上家公司用vnc做汽车面板的手机远程桌面,可以使用批量的,会很便宜。反正我接着就是研究开源的vnc。

---------------------撰写分割线-------------------------

开源vnc控件的使用

在网上找了找,资源虽然不多但还是有的。
下载了好多demo程序都不是很好。在多方尝试之后,我用“NVNC-master”里面提供的代码开发了客户端,使用Github上的一个仓库“vncFling2.0”搭建了vnc的客户端/服务端。

为什么选择两个组合呢?!
“NVNC-master”这个代码包里其实有服务端可客户端demo代码,但是页面效果很差,延迟有些高。我将服务端换成“vncFling2”,效果好了很多。
但是“vncFling2”没有代码 只有程序。因此我就直接偷懒,将服务端代码直接封装到一个程序中,到时候把服务端调用起来就ok了。

开源vnc

-----------------------分割线------------------------------
还没写完……

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值