被围观了 4,997 次

瘦客户端那些事儿 2011年7月07日

本文转自CoderZh的技术博客

一、瘦客户端那些事儿 - 开篇

人类活动最大的成本花费在哪里?我认为在沟通和学习上。我们从哇哇落地开始,就在不断的学习前人总结的经验。学校教育,大大加速了这一进程。随着互联网的发展,人们可以自由的分享知识和经验,使得我们平时遇到的问题基本上都可以从互联网上找到答案。因此,互联网当之无愧为人类最伟大的发明之一。它减少了多少 人们沟通和学习的成本啊!这个系列里,我要说说瘦客户端的那些事。涉及的知识都是来自互联网,所以,要感谢Google,感谢Wikipedia。最后,我将我学习和总结的知识再回馈回互联网,希望能对他人有所帮助,有所启发。

言归正传,让我们开始说说瘦客户那些事……

所谓“瘦客户端”,就是指,我们只需要一台配置一般的终端设备(PC电脑、手持设备等),就能拥有超计算机的计算处理能力。其实,这离我们并不遥远。BS应用的发展,已经让我们实现了只要一台配置一般的智能手机,就能通过Google完成亿万次的搜索计算。

 

上面的这个模型大家已经熟悉的不能再熟悉了。客户端发出指令,服务端接收指令,执行完运算后,将结果返回给客户端。但是,这个系列我要讲的,并不是上面这个模型,而是:

 

我们的手机(瘦客户端)不再是Google搜索中,搜索任务简单的发送者和接受者,而是一个更加实时的操作超级计算机的感受。我们的每一次鼠标移动,点击,键盘输入,触摸屏的滑动,仿佛手机本身就是一个超级计算机。有了这样的瘦客户端,我们不再需要购买价格昂贵、骨灰配置的电脑,而我们只需要一个很低配置的上网本,平板电脑,或是智能手机,就能一样畅快淋漓的玩魔兽世界、极品飞车。在未来科幻电影中的通话联络的智能手表、查看战斗指数的眼镜,都有可能实现。

同时,我们不再为程序的跨平台所担心。瘦客户端中,能跨平台执行各种应用程序,比如Windows的Word,Linux的OpenOffice,Mac里 的XCode。更让人惊喜的是,我们运行一款软件之前,不再需要经过“下载”、“安装”的步骤,而是立即使用。不管是多大的游戏,多复杂配置的软件。我甚至大胆推测一下,在未来,人们将不再使用Windows,Linux,Mac之类的操作系统,取而代之的将是完全基于网络的网络操作系统。而现有的这些操作系统,失去了个人用户也很难再维持发展,必将慢慢被淘汰。最后必将涌现出的,是各种基于不同瘦客户端协议的完全基于网络的操作系统。谷歌现在开发的chromium操作系统,正是符合这个发展趋势的,不过具体是怎样的,我没用过,也不好说。

在这个系列里,我尽量避免使用“云”之类炒的火热的词汇。我们见过了太多的所谓的“云”,十有八九是伪云,比如杀毒领域最大的忽悠云查杀。云计算和这里讲的瘦客户有一定的契合,但不完全相同。云计算强调的是大规模数据中心按需分配的计算能力,就像集中式发电厂。云计算是服务端的“胖”,瘦客户强调的是客户端的“瘦”,如果两者一结合,必将擦出火花。

未来并不遥远,我们能想的到的,都有人在尝试了。国外著名的有OnliveGaikaiOTOY等, 他们都实现了通过私有协议,在配置一般的机器上,远程玩像孤岛危机之类的大型游戏。特别是Onlive,由于其雄厚的实力,与硬件提供商、网络提供商、游 戏开发商都有深度的合作。比如,Onlive自主投资开发的定制硬件,和美国艺电有限公司(Electronic Arts)、育碧(Ubisoft)、Take-Two互动软件(Take-Two Interactive Software)、华纳兄弟、交互式娱乐和英佩数码美国艺电有限公司(Electronic Arts)、育碧(Ubisoft)、Take-Two互动软件(Take-Two Interactive Software)、华纳兄弟、交互式娱乐和英佩数码达成的深度合作。就连谷歌微软,都想买断Onlive的技术。

iPad展示OnLive Demo:http://v.youku.com/v_show/id_XMTgyMzYzNjI4.html

国内也有一家公司实现了这样的技术,叫云联科技。公司仅仅成立一年多,在中国现有的网络环境下,在没有定制硬件的前提下,就做出如此惊人的成果,不得不让人称叹。

但是,这么好的技术,为什么现在还没有普及开来呢?最大的障碍,是“延迟”和巨大的服务端消耗。

先来说说延迟。这里提到的是“延迟”,而不是“带宽”。为什么呢?延迟的英文是latency,带宽的英文是bandwidth。很多时候,人们会把两者混淆。有些人搞不清楚,为什么我的带宽提升到了联通4M,玩电信的服务器网游还会卡?带宽是指每秒最大的传输能力,延迟是指信号请求从发出到接收到所经过的时间。


误区:随着带宽越来越大,延迟也会越来越小。
上面的图已经很清楚,如果传输的数据未达到带宽限制,即便带宽再大,信号从发生到接收的时间T1-T0,只取决于其传输的速度和距离。假如服务器在美国,距离没办法改变,爱因斯坦说,速度的极限是光速。而光纤的传播速度也许只能达到40%光速。所以说,如果你要给远在4000公里之外的地方传输数据,比如从美国的加利福尼亚到马萨诸塞州,延迟不可能再低于44毫秒。

游戏或软件实际消耗的带宽其实并不多,而且,带宽在理论上是可以无限增加的,而延迟才是最大的问题,因为传播的速度不可能超过光速。比如,我以前用电信 512K带宽的网络玩剑三,非常的流畅。现在我用联通4M带宽玩剑三,延迟却很高。就像Gaikai这样的公司,由于距离的限制,目前也只能接受洛杉矶地 区玩家的试玩申请。

减少延迟的办法,在有限的情况下加快传输速率,以及尽可能的缩短传输的距离,比如,就近部署服务器。

另外一个障碍,是巨大的服务端消耗。我们可以想象,我们需要花费很多钱购买很好性能的机器才能流畅的玩孤岛危机之类的大型游戏。像Onlive这种云游戏服 务器供应商,相当于需要给我们每个人都配一台这样服务器。成本可见是巨大的。即便是Onlive自己定制的硬件,一台服务器同时也只能服务几个人。除了使用瘦客户端玩大型游戏,我们还可以用瘦客户端运行我们日常使用的软件或小游戏。无需下载,无需安装,一点即用,跨平台,多么有吸引力!而且,软件相对于游戏来说,不需要高清的传输画面,因此对带宽要求也低很多。软件开发商也不再需要针对各平台进行开发。理论上我们只需要一个版本的《植物大战僵尸》,就可以在iphone, android, pc等各种终端设备上运行。 

这样的技术,是如何实现的呢?像Onlive,Gaikai之类的公司,使用的是自己的专有传输协议,我无从考证。但是,接下来的文章,我会从现有的一些知名的或开源的远程传输协议开始,逐步深入技术细节,把我知道的那点瘦客户端的事告诉大家。

 

二、瘦客户端那些事儿 - 远程传输协议

上面说到了关于瘦客户端的一些现状和遐想,接下来我们开始探索这种技术实现的可能。要实现瘦客户端,最重要的是选择一种客户端和服务端都能理解的沟通方式,这种沟通方式就是通讯协议,或者远程传输协议。

本文不讨论Onlive之类的公司制定的私有未公开的传输协议,而是讨论一些现有的通用协议。其实大家对这些通用协议并不会陌生,他们分别是微软的RDP协议、Citrix的ICA协议、VNC的RFB协议、MIT的X11协议等等。

常见协议列表:

Software Protocol License
Citrix XenApp RDP, ICA Proprietary
FreeNX NX, RDP, RFB(VNC) GPL
LogMeIn Proprietary Proprietary
Neatx NX GPL
rdesktop RDP GPL
RealVNC RFB(VNC) GPL
UltraVNC RFB(VNC) GPL
Remote Desktop Services/Terminal Services RDP Proprietary
SSH with X forwarding X11 BSD
Symantec pcAnywhere Proprietary Proprietary
Citrix XenAppRDP ICA Proprietary

更详细的列表见:http://en.wikipedia.org/wiki/Comparison_of_remote_desktop_software

 

1、RDP协议

RDP全称是Remote Desktop Protocol,这就是我们平时在Windows里远程桌面使用的协议。使用mstsc.exe我们就可以远程连接到一台Windows机器的桌面进行操作了。在Windows2008里,有一个更吸引人的东西,那就是Terminal Services RemoteApp。

Terminal Services RemoteApp支持远程的执行单个应用程序,就好像这个应用程序是在本机运行的一样。有了RemoteApp,我们就可以实现在一台没有安装Office或者Visual Studio的客户端机器运行起来一个Excel或VS2010,而Excel和VS2010程序实际是安装在远程安装有RemoteApp服务端的机器。

设置远程应用程序:

 

RemoeApp架构图:

客户端可以直接使用.rdp快捷方式运行远程App,也可以在浏览器里里通过TS Web Access运行一个远程App(远程App并不是运行在浏览器里的)。

比如,在一台Vista的机器里,通过TS Web Access运行远程的WordPad(非Vista风格)。

运行效果如下:

微软的这项技术很酷,是吧。不过,RemoteApp仅限于Windows平台。

 

2、ICA协议

ICA全称是Independent Computing Architecture,即独立计算架构,它把应用程序的计算/执行逻辑与显示逻辑分离开来,把程序的计算/执行100%地保留在服务器端,而把运行结果图形化/界面化并通过网络传输到客户端,对于客户端而言,也只有键盘敲击和鼠标点击等会通过网络传给服务器。

ICA由Citrix公司设计的,Citrix可以算是这一领域的老大哥了,就连微软这样技术雄厚的公司,都是购买的Citrix的技术才做出上面的Remote Desktop和TS RemoteApp。技术的原创者是Citrix,因此Citrix拥有更大的优势,运用更多的创新,做出更好的产品出来。这个产品就是Citrix XenApp。

XenApp是个商业工具,我没有用过,自然算不上深入了,有兴趣的同学可以访问Citrix官网了解更多。下面是我找到的一个XenApp设计图:

 

3、RFB协议

RFB全称是Remote Frame Buffer,它是我们常用的VNC所使用的协议。RFB是一个远程图形用户的简单协议,因为它工作在帧缓存级别上,所以它可以应用于所有的窗口系统,例如:X11,Windows和Mac系统。远程终端用户使用机器(比如显示器、键盘、鼠标)的叫做RFB客户端,提供帧缓存变化的被称做RFB服务端。

 

由于使用的是帧缓存技术,因此VNC的性能一直被人所诟病。同时,VNC只能远程控制整个桌面,还没办法做到只单独运行一个程序。

 

4、X11协议

X11(X Window System core protocol)是由MIT于1984年设计出来的开源传输协议,一直发展至今,最新版本是X11R7.5。它是X Window System的基本协议。而X Window System系统生来就是为瘦客户服务的,从设计之初,它就被设计成计算和显示分离的架构,即程序的运行可以在一台计算机,而显示又在另外一台计算机。随着X11的不断演变发展,出现了各种不同形式的改良版本,其中最著名的就是NoMachine公司开发的NX协议,NX协议在X11的基础上,加入了缓存机制、压缩传输等,使其性能得到飞跃的提升。这也是我下一篇要重点介绍的。

X11的设计原则是:create Mechanism, not Policy,所以X故意没有规范应用程式的使用者界面 ,例如按钮 、选单 和视窗的标题栏等等。这些都由视窗管理器 (window managers)、GUI 构件工具包 、桌面环境 (desktop environments)或者应用程序指定的GUI(䠋如 POS机 )等等诸如此类的用户软件来提供。这样我们就可以理解,为什么Linux系统中会有诸多如Gnome,KDE之类桌面系统,同样使用X协议,绘制的界面却不尽相同。

 

要了解X11,一个非常重要的概念一定要弄清楚。就是X Server和X Client。通常Server是指服务器端,Cilent是指用户的客户端,但是X11中要反过来理解。X11中,用于显示画面的是Server,用于计算处理的是Client。所以,如果通过X11远程连接,用户端必须起一个X Server,远程应用程序实际通过远程的X Cilent来执行。

X11本身并不复杂,Server和Client交互的请求一共四种:Requests, Replies, Events, Errors。
1. Request: Client请求Server端返回信息或执行动作。
2. Reply: Server针对Request的返回。不是所有Request都有返回。
3. Event: Server发送的一些界面相关的事件给Client,例如:键盘、鼠标输入,窗口移动,Resize等等。
4. Error: 当Request请求无效时,Server发送错误信息给Cilent。

如果你正使用X Window System,比如Linux,Debian,Ubuntu等,马上就可以试试了。运行下面的命令,就可以运行一个远程的gedit(文本编辑器):

ssh -X -C root@192.168.x.x gedit

即使不是远程显示图像,本地执行的应用程序所使用的X11的架构也是一样的,都有一个Server和Client。我们可以通过修改Display环境变量,将画面显示到别处。

比如,Client端执行:

export DISPLAY=192.168.x.x:0

远程Display的X Server要接受Client的连接,使用xhost加入允许列表,Server端执行:

xhost + 192.168.x.x
然后,在Client端运行一个应用程序,比如:gedit,画面将显示在远程的Server端。 

好了,下篇将带大家了解NoMachine的NX的秘密。如果你对此有兴趣,请告诉我。

 

三、瘦客户端那些事儿 - NoMachine的秘密

上面我们介绍了各种远程传输协议用于实现瘦客户端,在各种协议当中,NX要我要重点推荐和介绍的。理由很简单,性能!大家都知道,网络带宽、网络传输是瘦客户端的重大瓶颈,谁能够在低带宽、慢速率的网络环境下工作良好,谁就是王者。本文将讲述NoMachine是如何做到这些的。

199x年,满怀梦想的Keith Packard,当时工作于SuSE,是XFree86的核心开发成员,一心想要开发一个在低带宽下依然性能完好的传输协议(LBX- Low Bandwidth X)。他为了LBX倾注心血,将LBX视为自己的孩子,然而最后他还是失败了,LBX最终并没有得到广泛应用。原因是LBX的性能还不够好。于是,他在2001年写一篇LBX的验尸报告 - An LBX Postmortem,以告慰后人,想要实现这样一个高性能的协议是多么的不可能。

2001年3月,XFree86的邮件组里横空出现了一篇题为About our effort at NoMachine的文章,作者是Gian Filippo Pinzari。文章隆重的介绍了经过作者三年研究,在低带宽下依然工作良好的,兼容RDP,VNC等协议的NX协议。Gian将NX的核心组件基于GPL开源出来,他说,“它就在这,大家都来用吧!”。

Gian的公司NoMachine开发的NX Client、Server等都是收费的产品。但是NX核心组件是开源的,于是出现了大量的开源的NX Client和NX Server。比如,NX Client就有OpenNXQtNX,NX Server又有FreeNXNeatX等等。

NoMachine的NX是如何做到的呢?NoMachine的秘密,主要有三个:
1. 在X协议的基础上,使用优化的压缩算法,进行压缩传输。压缩比达到10:1,甚至100:1。
2. 在客户端和服务端使用了缓存机制(Cache),避免同样的数据进行不必要的重复传输。
3. 减少客户端与服务端请求、回应的时间。

 

1、NX使用

NoMachien的NX主要分为两部分:NX Client和NX Server。NX Server的部署见文档,还不算复杂。部署完成后,就可以使用NX Client进行连接了。NX Client有Windows版本,Linux版本,Mac版本和Solaris版本。

点击“Configure”进行设置,可以看到,NX支持多种桌面协议。

如果要单独运行某个远程的应用程序,点击“Settings..”进行设置,比如,运行Linux中的星际译王(stardict)

以下是我在Win7下运行远程服务器中的文本编辑器(gedit)和星际译王(stardict)的效果:

NX可以设置共享本地磁盘,默认情况下,远程应用访问的远程设备。比如,在gedit中点击打开,可以看到

2、NX组件

我们知道,NX是在X11的基础上优化而来的。我们先来回忆以下X11的工作过程。

X Server和X Client是通过X11协议直接通讯的,我们之前讲到过,NX基于X11做了如下的优化:

1. 使用压缩传输。

2. 使用缓存机制。

下面就来看看NX是如何工作的:

可以看到,X Server和X Client不直接通讯了,而是通过NxProxy进行通讯。用户端的X Server误以为NxProxy就是X Client,使用原生的X11于其通讯,而用户端的NxProxy接收到X11协议数据后,经过压缩,再通过NX协议与服务端的NxProxy通讯。在服务端,NxProxy内嵌于NxAgent中,NxAgent再将NX协议与X11进行转化,并且冒充X Server与X Client进行通讯,从而达到优化的目的。NxAgent是从XNest演变过来的,既充当X Server又冒充X Client。

上图还可以看到,用户端和服务端的NxProxy都对数据进行了缓存。这样,他们之前传输数据时,可以将不变的数据缓存起来,传输的只是差异数据。

接下来我们来看看完整的交互过程:


当用户端的NxClient,比如OpenNX启动连接后,会通过客户端的一个NxSsh组件与服务端的NxServer建立连接(Connect),确认连通之后,NxSsh会向NxServer发出Start Session命令,命令包含需要启动桌面还是哪个应用程序,分辨率是多少等等。服务端收到命令后,准备好Session所需环境,然后启动NxAgent,内置的NxProxy也同时启动起来,同时,需要服务端执行的应用程序也被NxServer执行起来。随后,NxServer生成一个Xauth Cookie(相当于访问令牌)并返回给NxSsh,NxSsh收到Xauth Cookie后,再启动NxProxy,并且通过Xauth Cookie与服务端的NxProxy取得了联系。

Nxservice 用来把其他组件以服务方式启动的东西
NXWin NX的X Server,从cygwin/X演变过来的
Nxagent 从XNest演变而来。在服务端,作为一个假装的X Server,与服务端程序进行交互,接收绘图命令(X协议),但并不绘制任何窗口,而是将X协议转换为NX协议(压缩,减少传输次数),然后传递给服务端的nxproxy
Nxproxy 客户端和服务端都执行,保存缓存,并且互相传输NX数据。服务端中,nxproxy集成到了nxagent中
Nxssh 负责与服务端建立连接,并启动nxproxy
Xauth 用于用户验证,相关信息保存在.XAUTHORITY文件中

 

3、NX与VNC、RDP

前面我们讲过,NX基于X11,同时还能兼容VNC和RDP协议,那么它是如何兼容的呢?首先,我们再回头看看NX于X11是如何结合的。

这个图和我上面的“NX基本组件流程图”是一样的。可以看到,关键部分是nxagent,负责将X11与NX进行了转换。接下来,我们继续看通过NX连接VNC服务端的过程:


原来还是通过agent,将NX协议与RFB协议进行了转换。这样,用户通过NX连接VNC Server,其实是通过NX Server访问VNC Server,然后再将信息通过NX协议传输回来,最终还是通过X Display Server在用户本地显示。RDP也是同样的原理:

下面是一个完整的图:

 

4、NX Library编译

NX的Library使用GPL开源协议,意味着我们也可以使用NX Library开发我们自己的NX Server或Client。首先,我们必须解决编译的问题。NX Library的编译过程并不复杂。

在Linux环境下,参考官方文档:编译步骤如下:

需要先安装:
yum install libjpeg
openssl-devel
netcat
expect 

源码安装libpng
wget http://download.sourceforge.net/libpng/libpng-1.4.3.tar.gz

下载以下包,比如,下载到:~/NX
nxcomp-3.3.0-4.tar.gz
nxproxy-3.3.0-2.tar.gz
nxagent-3.3.0-13.tar.gz
nxcompext-3.3.0-4.tar.gz
nxauth-3.3.0-1.tar.gz
nxcompshad-3.3.0-3.tar.gz
nx-X11-3.3.0-6.tar.gz

解压所有:
find . -name "*tar.gz" -exec tar -zxf {} \;

编译:
cd nx-X11
/make World
cd ..
cd nxproxy
./configure && make

cp -a nx-X11/lib/X11/libX11.so* /usr/NX/lib
cp -a nx-X11/lib/Xext/libXext.so* /usr/NX/lib
cp -a nx-X11/lib/Xrender/libXrender.so* /usr/NX/lib
cp -a nxcomp/libXcomp.so* /usr/NX/lib
cp -a nxcompext/libXcompext.so* /usr/NX/lib
cp -a nxcompshad/libXcompshad.so* /usr/NX/lib
cp -a nx-X11/programs/Xserver/nxagent /usr/NX/bin
cp -a nxproxy/nxproxy /usr/NX/bin

设置LD_LIBRARY_PATH
export LD_LIBRARY_PATH=/usr/NX/lib:$LD_LIBRARY_PATH

这时,/usr/NX/bin/nxproxy 和 /usr/NX/bin/nxagent 应该可以用了

Window平台下,NXWin的编译过程,参考这里

下载:
nx-X11-compat-X.Y.Z-N.tar.gz
nxwin-X.Y.Z-N.tar.gz
nxauth-X.Y.Z-N.tar.gz
nxcomp-X.Y.Z-N.tar.gz在cygwin中,执行: 

# tar zxvf nx-X11-compat-X.Y.Z-N.tar.gz
# tar zxvf nxwin-X.Y.Z-N.tar.gz
# tar zxvf nxauth-X.Y.Z-N.tar.gz
# tar zxvf nxcomp-X.Y.Z-N.tar.gz
# cd nxcomp
# ./configure
# make
# cd ..
# cd nx-X11
# make World

5、NX Cilent开发步骤

基于NX Library开发一个NX Client并不是什么难事,在freenx的svn库里有好几个NX Client工程,比如:qtnx,还有Python的实现版本gnx(仅限linux系统),因此,可以参照这些工程的实现。

svn co http://svn.berlios.de/svnroot/repos/freenx/trunk freenx

NX Client与NX Server的交互过程见:NX Client开发步骤

 

 
目前有0条回应
Comment
Trackback
你目前的身份是游客,请输入昵称和电邮!

Verify Code   If you cannot see the CheckCode image,please refresh the page again!