开发宝典:基于分布式对象的网游程序结构设计
提高游戏的可体验性,易安装性,乃至于不需要安装。直接在游戏中体验游戏的优劣,比之宣传广告,能够给玩家更加直观的感受,是最佳的游戏推广方式。这应该是游戏开发的一个趋势。易安装,不安装,类网页游戏应该成为游戏发展的一个方向。
基于分布式对象的网游程序结构设计(1) - 开篇
Web浏览器和游戏毕竟不是一个事物。Html超文本协议(虽有VB,javascript等脚本语言作为补充)也不完全适用于网游。之所以类比,是进一步强调免安装,易于体验性的重要性。当然,Web技术也在不断发展,不仅出现很多Web浏览器上运行的网游,其图形和图像方面的功能也在不断丰富,本文将在第二部分,对Web相关技术的发展进行一个探讨。
基于分布式对象的网游程序结构设计(2) -Web技术的发展和网页游戏
Web技术之所以能够如此快速发展,究其根源,在于基于BS结构的分布式应用,客户端不再需要部署其它软件,降低了发布成本和维护成本。并且使用浏览器,能够浏览各种网页,且与平台无关,不管网页服务器运行在Windows,Unix,还是其它操作系统上面。如果不是这个特性,Web技术和浏览器应用不会发展如此之快,这点谁都不能够否认。也正是由于这点特性,带动了整个Internet的发展,促进了Web相关的各种技术的研究。
基于分布式对象的网游程序结构设计(3) - 分布式组件模型DCOM/COBRA
分布式组件技术是一种CS结构,其出现,是为了简化网络编程,开发者不再需要关心具体如何进行底层通信。目前比较有代表性的有两种:DCOM和COBRA。DCOM使用ORPC机制,COM服务器创建对象类的实例,一个COM对象可以具有多个接口,分别代表不同的观察角度和不同的对象行为。客户端获取对象接口的指针,通过指针调用相关的方法。
基于分布式对象的网游程序结构设计(4)-SRP分布式对象的概念
作为游戏中的一个角色。在服务器端和客户端同时存在,服务器端负责角色对象的逻辑,以及各种属性的更新;客户端负责角色对象的显示,与玩家进行交互。这应该是一种非常典型的分布式对象模式。但是目前的分布式对象技术,能够支持这种模式吗;答案是不支持,没有使用Web Service或者 Cobra/DCom开发的游戏。因此可以说目前的分布式对象的 概念,还存在不完善的地方。
==================================================================================================================
基于分布式对象的网游程序结构设计(1)
如何吸引玩家安装或者体验我们的游戏;
如何留住玩家,同时吸引更多的玩家。
其中第一个问题是最关键的,如果玩家连安装和体验都不进行,如何谈得上留住玩家,更谈不上吸引更多玩家。目前,网游市场日趋激烈,每年新增的网游都有几十款之多。对于一个玩家来说,每款都下载,都去体验一下;不管游戏是否好玩,是否符合自己的品味,先花几个小时下载安装,不喜欢的话再卸载,其间还可能遇到各种各样的问题,耗费时间和精力,是不会有玩家这样做的。
因此对于一款游戏,一款好游戏。在推广的初期,需要大量的广告和宣传投入。这对于一个小规模的公司或者企业来说,无疑是一个巨大的负担。试想,玩家连装都不安装,如何谈得上留住玩家,拓展玩家。
提高游戏的可体验性,易安装性,乃至于不需要安装。直接在游戏中体验游戏的优劣,比之宣传广告,能够给玩家更加直观的感受,是最佳的游戏推广方式。这应该是游戏开发的一个趋势。易安装,不安装,类网页游戏应该成为游戏发展的一个方向。
类网页游戏是一个概念,不是专指在浏览器中运行的游戏,而是指任何不需要下载和安装的网络游戏。近二十几年来,internet技术发展很快,甚至连中小学生都能够上网,浏览各种信息。这一方面归功于底层网络的建设和发展,也要归功于Web浏览器技术的发展。如果每个网站制作的页面,都需要下载安装之后才能够进行浏览,那么,internet技术不会发展如此之快,也不会这么快进入到信息时代。
当然,Web浏览器和游戏毕竟不是一个事物。Html超文本协议(虽有VB,javascript等脚本语言作为补充)也不完全适用于网游。之所以类比,是进一步强调免安装,易于体验性的重要性。当然,Web技术也在不断发展,不仅出现很多Web浏览器上运行的网游,其图形和图像方面的功能也在不断丰富,本文将在第二部分,对Web相关技术的发展进行一个探讨。
针对免安装,这里提出一种新的基于分布式对象的网游程序架构,通过分布式对象管理功能,构建一个类似于Web浏览器的通用网游平台,实现网游的免安装特性。内容和章节如下安排:
Web相关技术的发展和网页游戏。
分布式组件模型DCOM/COBRA
分布式对象的概念
分布式对象的特点
分布式对象引出的系列技术
基于分布式对象的网游程序结构和优点
这里所提出或者提及的观点,不是空洞的概念。本文分析了Web技术发展中可能遇到的问题,指出了DCOM和COBRA等组件模型存在的缺憾,随之提出一种分布式的对象模型,并基于此模型设计了一种类网页的游戏程序结构。文中提到的大部分概念,目前已经由星河平台在最新发布的版本实现。其最新版本同时包含有一个相对完整的2D网游引擎和相关工具,可用于大型2D网游的开发。有兴趣的朋友可访问网站http://www.srplab.com。
在星河平台上开发应用,据其特点,或许可以不必担心受平台的限制。一方面,在平台上开发的应用脚本,可以完全导出为XML文本文件;另一方面,开发的对象的动态库,基于平台相对简单的规范,依据其接口,完全可以自行进行开发(这与Dcom,Cobra,Web服务等技术不同,相对比较简单,并且诸如DCOM,已经成为操作系统的一部分,纵然知道其原理,自行开发DCOM模块基本是不可能的)当然,这不是必要的,星河工作室将一直维护星河平台,共同建立一个统一的网游开发平台,减少重复开发导致的资源浪费。使游戏公司将更多的精力放在游戏的内容开发上,打造更多的精品游戏。
虽然目前星河平台仅仅实现2D部分,但是,到3D可以平滑过渡,目前定义的2D对象和类,仍然可以使用。下图是一个Irrlicht引擎中的一个例子,使用目前平台2D引擎中的对象,完全可以嵌入到3D的例子中显示帧频[显示的帧频是一个平台中的2D Label对象]:
==================================================================================================================
基于分布式对象的网游程序结构设计(2)
Web技术之所以能够如此快速发展,究其根源,在于基于BS结构的分布式应用,客户端不再需要部署其它软件,降低了发布成本和维护成本。并且使用浏览器,能够浏览各种网页,且与平台无关,不管网页服务器运行在Windows,Unix,还是其它操作系统上面。如果不是这个特性,Web技术和浏览器应用不会发展如此之快,这点谁都不能够否认。也正是由于这点特性,带动了整个Internet的发展,促进了Web相关的各种技术的研究。
提到Web,我们都会联想到各种名词和概念,Http,Java,ASP,SOAP等等,一方面反映了技术发展蓬勃向上,欣欣向荣的趋势,也在另一个侧面,说明了Web技术发展本身缺乏系统性和完整性。也就是说,在各种Web应用过程中,发现缺少什么,还有什么不方便,那么就补充什么,继而引入新的概念和技术。
最早超文本描述语言HTML是静态的,在客户端表现力不丰富。服务器端存储的网页,只能够下载到客户端进行显示浏览,客户端的操作需要提交到服务器进行处理,即便类似于简单的输入参数的验证,在客户点击确认之后,也由服务器进行校验;如果输入错误,客户端需要等到几秒甚至几十秒的时间,才能够得到反馈。改变这一现状的是1995年,Netscape引入的Javascript,使得在客户端能够执行脚本。解决了这一问题,程序员可以使用脚本语言,创建内容和表现力更加丰富的HTML页面。
AJAX进一步提高了页面的表现力和客户的体验。AjAX不是一个新的技术,1999年,微软的IE5就支持这种特性,只不过当时并没有得到认可。AJAX的核心思想是异步操作,可以通过JAVAScript和VBScript调用。客户端在提交请求之后,不再需要等待响应。当收到服务器响应之后,使用JavaScript和CSS更新页面相应的部分,而不需要更新整个页面。
在服务器端,最早的Web服务器只是简单的接收Http请求,并将存储在服务器上的Html页面,传送给浏览器。CGI技术的出现,使动态页面生成成为可能。允许服务器端的应用程序,根据客户端的请求,动态生成HTML页面。使客户端和服务器端能够进行动态信息交换,可以根据客户端请求,当前服务状态,以及数据库的内容,为客户订制页面。随着CGI技术的发展,聊天室,论坛,电子商务等各种各样的Web应用程序也蓬勃兴起。
早期的CGI是可执行程序,用C/C++等语言开发。为了简化CGI程序的修改,发布和编译。逐渐采用脚本语言编写CGI程序。最早出现的是Perl语言编写的CGI程序,后来出现了多种脚本语言,PHP,ASP,Servelet等。
Web技术的发展,也促进了基于Web的各种分布式应用的技术的提出和发展,最具代表性的是Web Service技术。简单的说,Web Service就是一种应用程序,可以使用标准互联网协议进行远程调用。其核心的内容是简单对象访问协议SOAP,和Web Service描述语言(WSDL)。SOAP定义了消息格式,以及如何通过Http协议传输SOAP。WSDl用于描述Web Service及其函数,参数,以及返回值。WSDL是文本格式,可以通过工具,生成对应的调用的桩函数代码。
基于浏览器Web应用和服务可以用下面的图形象的描述:
HTML描述了Web Server和浏览器之间的数据格式。WSDL描述了Web Service的特性,但是它不描述Web Service和浏览器之间的数据包格式。
从概念上讲,Web Server及其上的各种应用,诸如:各种网站,论坛,博克等,都可以看作是Web Service,它们提供的是一种信息服务。目前对Web Service的概念诠释为一种可以通过Web远程访问的者一组函数库。根据词义来说,服务和函数不是一个概念,正如函数不是应用程序一样。一组函数放在一起,绝不能够说是一个应用程序,应用程序具有整体上的完整性,能够对外提供某些功能。从这一点上说,对于稍微复杂一些的Web服务,都不是简简单单的远程调用。因此说,目前Web Sevice的发展还处于初级阶段,就好像90年代初的静态网页一样,随其发展和需求的不断增加和明确,肯定会不断出现新的概念和技术。
在Web Service中,比较重要的两个名词是SOAP和WSDL。SOAP描述了调用接口的传输格式,WSDL描述了提供的服务的内容,参数,返回数值等。在Web技术的发展过程中,形成了一种既定的概念或者结论,那就是服务器端和客户端是独立的应用,两者之间只在底层传输接口上进行交互。虽然也出现了一些浏览器的插件,将某些功能由服务器端下载到客户端执行,但是并没有打破这种概念。这就要求客户端,特别是客户端的开发者,从接口上去观察和理解Web服务。虽然WSDL可以描述服务的内容参数,但是随着服务变得越来越大,功能越来越多,各式各样,不同类型的服务,势必导致WSDL越来越复杂。
即便简单的Web服务,用WSDL描述起来也不简单;其文本格式,与其说是为了方便进行开发人员参考,还不如说主要为避免了通信上的问题(不同操作系统,不同模式的计算机都能够解析)。作为开发者,直接使用底层的Web Service接口,难度比较大。相当于将通信处理,接口的编解码全部由开发者承担,而且不同的Web服务,这些是不同的,可以想象是多么大的一个工作量;因此,一般是利用一些工具,根据WSDL生成客户端调用的桩,自动生成的代码有时不能够完全满足要求,此时还需要进行一些直接面对底层的开发工作。
客户端使用桩函数进行开发,上图略为做些修正:
Web Service Stub虽然是自动生成的,但是其代表了Web Service定义的功能在浏览器或者客户端的映射。开发者直接了解Stub提供的功能和如何调用即可,不再需要关心如何编码,如何传输,也不用关系如何在Stub和Web Service之间传递消息的。这不仅仅简化了开发工作,而且在概念和Web Service整体架构上,前进了很大的一步。不再通过传输接口调用服务器提供的Web服务,而是在本地,直接调用Web服务的桩,是一个概念和思路的转变。
试想一下,如果我们将Web Service对上的接口标准化,将会是什么结果呢?明显一点,在Web Service Stub与Web Service服务器之间的过程,对使用者来说变成透明的,不再需要关心。Web Service可以采用任何语言实现,可以用Javascript,VBScript,还可以是效率高的C/C++,两者之间的通信是Web服务的内部事务,可以使用SOAP,也可以使用任何自定义的或者任何熟知的协议。这将对Web技术的发展产生深远的意义。
在这种思想下,上图修正如下:
Web Service Stub对上的标准接口,需要体现Web Service提供的各种服务,需要能够描述任何Web服务。最适合的方法是采用对象的概念,描述一个Web服务。一个Web服务,由多个对象组成,每个对象有属性和方法。客户端可以通过对象的方法,完成对服务的调用。比如,Web Service中包含有一个当前天气的对象,有温度,风速等属性,在客户端,直接读取对象的属性,即可完成对Web Service的调用。
基于这种概念提出的模型,就是本文重点研究的分布式对象模型,如下图:
其中,蓝色的部分构成了分布式对象平台。
基于BS的各种Web应用,其优点是不需要部署和安装。但是,HTML,HTTP最初都是针对文本信息的,虽然扩充了很多内容,诸如:动态网页,客户端插件等,力求丰富客户端的功能。但是其本身存在一些固有的缺憾,这对某些方面的应用,如网页游戏的应用,将是一个很大的限制。
1. 数据和资源文件反复下载
在BS应用中,通过URL定位资源或者数据文件,在打开网页时,虽然图像等文件已经下载到本地了,但是在刷新时,还需要下载。虽然浏览器都提供了本地的Cache,针对相同的URL可以减少一些重复下载。但是,基于URL的缓存并不能够说明数据的内容是否发生变化了,是否应该下载,这在有些应用的时候会产生一些问题,以致于对于同一资源,需要使用不同的URL才能够在客户端正确刷新。数据本身的变化(例如图片发生变化),需要通过更新URL才能够正确下载,这本身就不是一种合理的处理方式。
2. 不方便维护客户端状态维护
服务器端不维护客户的状态,客户端重新打开网页,与第一次打开网页,对于服务器来说,没有什么不同。虽然使用Cookie能够在一定程度上解决这个问题,但是不是一种很好的方式,Cookie每次在客户端和服务器端的传输,都增加了通信的开销,再者Cookie在数量和大小上是有限制的。
3. 服务器端不能够主动发起数据的传输。
由于服务器端与客户端是无连接的,在某些应用场合,如果服务器端需要主动给客户端发消息,比如实现聊天室的功能,一个用户的发言,需要广播给其他客户端,实现就存在一些困难,需要用其它途径解决。这点恰巧是网友中必须实现的重要功能。
4. 编码简单,通信传输的开销大
在服务器和客户端传输使用文本方式编码,对于需要大量信息交互和频繁交互的应用场景下,通信传输占据的开销很大。
基于BS结构的网页游戏,不可避免的存在这些问题。近些年来,网页游戏作为网络游戏的一个特殊的分支,发展也很快。其优点来自于BS架构,不需要安装,并且可以穿越防火墙(一般防火墙对于80或者8080端口都是开放的),因此针对与上班一族,有着先天的优势。在网站http://www.webgame.com.cn上,有当前很多流行的网页游戏介绍。
目前网页游戏的特点都是偏向于休闲,交互性不是很强,画面表现力也不丰富。网页游戏只能够在游戏内容上,力求新颖,吸引玩家。其进一步,特别是在表现力和交互性上的发展,将受到BS结构上述问题的限制。
==================================================================================================================
虽然在游戏开发中,很少使用DCOM/COBRA分布式组件技术。但是作为一种分布式技术,这里也分析一下存在的问题。
分布式组件技术是一种CS结构,其出现,是为了简化网络编程,开发者不再需要关心具体如何进行底层通信。目前比较有代表性的有两种:DCOM和COBRA。DCOM使用ORPC机制,COM服务器创建对象类的实例,一个COM对象可以具有多个接口,分别代表不同的观察角度和不同的对象行为。客户端获取对象接口的指针,通过指针调用相关的方法。
COBRA是由OMG(Object Manage Group)提出的,其核心是ORB(Object Request Broker)。作为一个透明的总线式模型,可以与本地或者远程的对象进行交互。COBRA对象对外呈现一组接口,客户端获取对象的引用,通过引用进行方法的调用。ORB负责查找对象的实现,发送请求并处理返回结果。
两种组件模型都采用CS模式的通信。为了调用一个服务,客户端需要调用远程对象实现的方法。服务器端提供的服务,封装成为一个对象,对象的接口使用IDL(Interface Definition Language)描述。客户端通过调用IDL中定义的方法与服务器端进行交互,不用关心实际对象的实现。支持面向对象的一些特性,例如:数据封装,多态,继承。COBRA支持多重继承,DCOM不支持,但是一个对象可以有多个接口。
为了调用一个远程的方法,客户端调用本地的桩函数,桩函数将参数封装成为请求,将请求发送给服务器端。服务器端将请求传递给Server Stub,对参数进行解包,并调用实际的函数。在DCOM中,客户端的桩称为proxy,服务器端的桩称为stub;在COBRA中,客户端的桩称为stub,服务器端的桩称为skeleton。
假设有一种Grid对象服务,Grid对象维护一个二维的整数,支持两组方法:第一组是get和set,可以设置某个格子上的数值;第二组是reset,复位某个格子上的数值。则对于COBRA,需要定义三个接口,接口Grid1支持get和set;接口Grid2支持reset;接口Grid继承Grid1,Grid2。使用DCOM,则定义两种IGrid1和IGrid2。
采用DCOM调用,则客户端端的处理步骤如下:
1. 客户端调用COM库函数CoCreateInstance,使用CLSID_Grid和IID_IGrid1作为参数。
2. COM库请求服务器创建对象
3. 服务器端COM获取指向CLSID_Grid的类工厂指针,调用其CreateInstance函数。
4. 类工厂创建一个对象,然后服务器端调用QueryIntreface获取指向IID_IGrid1接口的指针。
5. COM库将指向pIGrid1接口的指针返回给客户。
6. 客户端调用pIGrid1接口的get方法。
采用COBRA调用,则客户端端的处理步骤如下:
1. 客户端调用桩函数grid::_bind()。
2. ORB向Server发起请求
3. 服务器端创建实例,调用CORBA::BOA::impl_is_ready(),通知ORB对象已经准备好。
4. ORB向客户端返回对象的引用
5. 客户端调用对象的方法。
在上面的处理步骤中每个步骤,COM库或者ORB都需要进行很多操作,因此调用的效率不高,只能够进行粗粒度的调用。例如一个服务上有几十个对象,如果通过上述方法获取对象的内容并进行显示,处理和流程将会多么复杂。
对象引用在客户端应用中创建,并且是动态创建的,因此当服务器端组件是细粒度,对象很多时,这种代价是非常高的。
相比Web Service,WSDL描述的服务方法参数和返回值,类似于组件对外的接口,但是在进行Web Service进行调用时,不需要创建对象,也没有对象的概念。而是直接使用URL,定位到了需要调用的服务器端的对象。因此,Web Service与组件模型相比,调用需要的交互要少一些。
在DCOM和COBRA中,由于对象的创建导致交互很多,不适合于细粒度的模型。但是如果将服务器端组件的对象预先创建好,并引入对象管理功能,在客户端访问服务器端时,一次性的在客户端创建相应的对象,则可以解决这个问题,如下图:
DCOM和COBRA在开发和部署上都相对复杂,影响了其发展和应用。
==================================================================================================================
SRP分布式对象的概念
作为游戏中的一个角色。在服务器端和客户端同时存在,服务器端负责角色对象的逻辑,以及各种属性的更新;客户端负责角色对象的显示,与玩家进行交互。这应该是一种非常典型的分布式对象模式。但是目前的分布式对象技术,能够支持这种模式吗;答案是不支持,没有使用Web Service或者Cobra/DCom开发的游戏。因此可以说目前的分布式对象的 概念,还存在不完善的地方。本节针对此问题进行讨论,并提出SRP分布式对象的概念。
目前对于分布式对象的概念,一般指RMI、COBRA、DCOM等分布式组件技术。但是我们认为对象应该是具有属性的,不应该只有方法;在面向对象编程语言中的对象概念更加贴切。而目前的组件技术,都是只提供了一个抽象的接口,即便是Web Service,也只供了远程调用的方法(可以看作是一个抽象的接口),并没有提及属性,而且也不支持定义属性。在分布式应用中,对象的属性重要吗?目前的组件技术和Web Service技术,都没有定义属性,不是发展的很好,也能够方便的应用于各种场合下吗?
回答这个问题,这里简单的给出一个例子:对象在某些状态下(例如:忙),某些接口不能够调用(例如:查询),调用会返回错误。按照目前组件技术的描述方法,如下:
Interface objectclass{
char *Query( in int arg, out int result);
};
对于该组件的使用者,如何调用呢,反复调用Query函数,直到正确的结果吗?这个例子非常简单,但是使用目前的分布式组件技术,很难实现。对象的属性分布到客户端(调用者),有利于客户端根据对象的状态,更加灵活地进行服务调用,为客户提供更好的服务。仅仅是对象的属性分布到客户端就够了吗?
回想前面对于Web技术的发展过程中,javascript为什么引入,并得到迅速发展。在客户端和服务器端进行交互时,如果客户端能够进行一些预先的处理,也能够提供更好的服务。比如简单类似输入参数的校验问题,如果在客户端能够进行,则不再需要再发送到服务器,并等待几秒甚至几十秒之后,再得到错误的反馈。这需要把部分对象的脚本(甚至代码)也需要部署到客户端,
Web Service和组件模型提出了一种新的编程模型,这也是出现和发展起来的原因。但是快速发展不能够说明这些技术本身不存在问题,对于相对复杂的Web服务,细粒度的组建服务,这些技术还不是很成熟,或者说,不能够进行处理。本文提出的SRP分布式对象模型,解决了这些问题。
这里提出的分布式对象的概念如下:
对象具有属性,方法和执行脚本(代码)。对象在服务器端和客户端同时存在,并且客户端对象有与服务器端相同的属性。客户端对象和服务器端对象通过唯一标识(一般使用UUID)建立一一对应关系。
对象的属性,脚本(代码)如何分布到客户端,这就需要分布式对象管理系统。
针对上述的例子,如下:
Interface objectclass{
Int BusyFlag;
char *Query( in int arg, out int result);
};
这样客户端首先判断BusyFlag是否设置,如果设置,则不进行调用,如果没有设置,则可以调用。
采用对象的概念,分布式对象管理系统可以为上层的应用,提供一个统一的接口,即分布式对象管理接口。通过该接口,可以获取对象,对象的属性,调用对象的方法,并接收对象的异步事件。
对于前面Web技术和组件技术存在的问题,采用分布式对象的技术,则可以如下处理:
1. 数据和资源文件反复下载
每种数据或者资源,都可以定义为一个对象,对象定义属性,说明数据或者资源的版本;如果数据发生变化,则对象对应的版本属性发生变化,客户端判断属性发生变化之后,再重新下载。如果相同,则不需要下载,直接使用本地缓存的数据即可。
2. 不方便维护客户端状态维护
分布式对象管理,支持常连接模式,以方便支持需要维护状态的应用。
3. 服务器端不能够主动发起数据的传输。
分布式对象管理,支持常连接模式,服务器可以通过该连接,修改对象的属性,与客户端进行通信。
4. 编码简单,通信传输的开销大
分布式对象管理,支持使用自定义通信,在某些追求效率的应用场合,
5. 细粒度模型
通过分布式对象管理,对象分布到客户端,客户端直接使用对象的属性或者调用对象的方法。不再需要针对每个对象,执行远程创建的过程,因此能够支持成千上午个对象。
这种分布式对象模型,能够用于游戏中吗,答案是可以。对象属性同时在服务器和客户端存在,服务器端更新对象属性之后,由分布式对象管理将属性同步到客户端,客户端刷新显示。客户端可以调用服务器端的对象的方法,服务器进行逻辑控制,修改对象的属性。
==================================================================================================================
==================================================================================================================