蒸膳美加盟靠谱吗:Sun公司开源游戏服务器Project Darkstar Server——(Sun game server , 简称 sgs)学习笔记(一):sgs简介 - 木瓜网络 - 博客园

来源:百度文库 编辑:九乡新闻网 时间:2024/04/29 10:08:48

SGS 提供的主要功能 :

服务器端的扩展 : 传统的扩展方法是将整个游戏区域分成多个区 , 不同的区运行在不同的游戏服务器上 . 这带来两个问题 , 一个是处于不同区的玩家不能互相交互 ,另外一个是如果某个区发生的动作较少时 , 会出现服务器资源未被充分利用的情况 . 而在 sgs 的处理方式下 ,所有的处理被分割成为一个个小的执行单元 ( 称为 task), 这些 task 可以在组成网络的任何 sgs 服务器上执行 , 当用户增加时 , 系统自动增加处理线程 , 不再需要为了扩展而将不同的区分配到不同的服务器上面 . 这样既提高了资源利用率 , 又可以让所有的玩家进行交互 .

数据完整性 : sgs 提供了一个分布式的数据存储 , 一个 task 需要访问数据时 , 通过数据存储 api 进行访问 , 数据访问具有事务支持 , 当两个 task 发生冲突时 ,sgs 会自动协调 , 较年轻的 task 重新调度等待执行 , 而年老的 task 将会执行并直到结束 . 当前版本中的 sgs 数据存储未使用关系数据库 , 而是使用了 berkeley db. 任何 java 对象 , 只要实现了 ManagedObject 标志接口 和 Serializable 接口后即可自动透明存储 .(sgs 的存储机制好像是可扩展的 , 论坛上已经看到有人在讨论 mysql 的存储插件 )

简单的编程模型 : 从应用开发的角度来看 ,sgs 提供了 api 屏蔽了多数的底层复杂性 , 例如线程调度 , 事务处理 , 等等 , 应用程序只需要开发并装配自己的对象 , 监听响应客户端事件 , 自己管理持久化的 ManagedObject 对象生命周期即可 .

两种通信模型 : 一种是 client/server 的通信 , 即每个 client 只和 server 通信 , 由 server 来负责数据的处理和转发 . 另外一种是 channel 机制 ( 类似一对多的广播 ),channel 由 server 创建并维护 , 每个 channel 可以添加多个 client,server 可以监听 channel 中的所有通信或者具体某个 client 的通信 . 也可以给 channel 中的全部或者部分 client 发送消息 . 加入 channel 的 client 可以收到其它任何 client 发送的消息 .channel下面 client 之间的通信不需要 server 端的介入 . 由于所有通信的数据格式都是字节数组 , 所以应用程序需要开发自己的应用层协议.

可扩展的机制 : sgs 应用程序访问数据 , 使用 channel, 创建 task 都是通过 ”Manager” 来进行的 . 目前一共有三种缺省的 ”Manager” ,DataManager,ChannelManager,Taskmanager. 但可以扩展开发自己的 Manager, 例如在 sgs 中要求 task 应该是尽量快的执行 (task 允许执行的时间上限可以配置 ) , 所以如果出现调用可能导致阻塞的系统方法时 , 就需要开发一个扩展的 Manager.

Darkstar 项目为游戏开发者提供了一个开发环境。在该环境中,开发者只需通过使用虚拟环境的固有并行性就可以扩展该环境,而不需要学习分布式计算或多线程编程。Darkstar项目实现了开发者的梦想,服务器端应用程序代码可以运行在单机器单线程上。事实上,服务器执行的任务可以分布运行在许多机器和线程上,在某种程度上增大了扩展和容差能力。系统优化了游戏应用程序需要的低延迟时间。Darkstar项目集群的每一个节点都运行了一份游戏服务器代码(由游戏开发者编写,包含游戏逻辑)的拷贝,这些代码都位于 Darkstar项目协议栈之上。协议栈以一组服务的方式显示给游戏服务器。这些服务控制游戏的持久状态、通信通道,以及任务的创建和调用。任务,游戏服务器的工作单元,响应玩家或一些内部触发器发出的消息,在一次事务处理中隐式地执行。并行控制对游戏开发者而言是透明的,当一个任务需要访问某个已被另一个任务锁定的对象时,处于事务处理中的任务将被包装且放弃运行,稍后会被重新调度运行。任务的事务性质也确保了相关任务可以建立串行的执行序列。

可以通过使用多个线程来扩展单个节点,这些线程是由任务调度程序控制的。更进一步的扩展允许多个节点(可能是一台实际机器或者是一台虚拟机)协作运行同一个游戏。这项功能是由 Darkstar项目的服务结构提供的,应用程序运行在基础结构上,确保了系统执行的任何任务都可以从一台机器迁移到另一台机器,以平衡负载和增强可靠性。

所有游戏对象存在的时间都比单个任务存在的时间长,在数据服务中需要创建它们并将将其保存在数据库中。任务在操作任何对象之前,必须先读取它们,确保它们在以最新的状态工作。数据服务由数据库支持。当前数据库服务器使用的是 BerkeleyDB,一方面因为其性能,另一方面因为它是开源软件。然而,数据服务间的接口和后台数据库也可以是其他数据库,比如 Postgres 或者mySQL。

Darkstar 项目通过会话服务和通道服务协调通信。会话服务提供游戏客户端和游戏服务器的直接通信。通道服务提供了一个发布/订阅通信机制,通道上的消息可以被传送给在该通道上的所有订阅者;此机制提供客户端和客户端谈话服务。这两种通信形式都是基于由底层操作系统提供的基本通信机制的抽象概念,可以在Darkstar项目集群的任何特殊节点中释放通信端点。这样,服务器端集群中的任何特殊中间节点的通信都是自由的。这些通道可以从一个服务器移到另一个服务器,以优化性能或进行故障恢复。

如果将数据服务的用途和通信通道的可移植性结合使用,那么各个任务就可以运行在任意机器上,且不会改变任务的执行功能。也就是说,负载可以从一个机器移到另一个机器,在移动过程中,通过简单地增加更多机器到运行游戏的节点集上,就可以增加或减少负载容量。此外,Darkstar 项目基础结构内的元服务将参与动态移动任务,确保数据访问和通信的位置。这些服务,对游戏开发者来说是不可见的,他们可以观测Darkstar 项目基础结构中的基本服务来决定系统节点的最佳负载,检测故障并且恢复到初始状态,检测新的资源以便在将来需要使可以增加到整个系统。

第三方的厂商可以提高 Darkstar项目的基本服务。新服务可以被引进并参加任务的执行活动。这些服务可以与事务机制进行交互,并观测使用元服务的整个系统。例如,它将可以访问完整的关系型数据库,跟踪游戏统计信息,且允许查询这些统计信息,以及在不需要游戏数据服务存储信息的情况下扩大游戏管理能力,优化许多游戏需要的低访问延迟性。

项目优点总结


Darkstar 项目架构具有许多重要优点,包括:

  1. 一个简单的开发模型

    虽 然 Darkstar 项目基础结构提供的是可扩展的多线程多节点环境,但是游戏服务器开发者却如同在单机器和单线程的环境中编写代码。该模型最小化或消除了数据存取竞争、线程 调度和工作负载分布问题,使得开发者可以集中精力编写游戏,而不必关注可伸缩的系统机制。众所周知,编写一个复杂、多线程的游戏应用程序是一件困难且辛苦 的事情,而拥有成功开发此类应用程序经验和技能的程序员又少之又少。使用 Darkstar 项目基础结构,开发复杂性将会极大地减小,且程序员需要的技能仅仅与游戏有关而与环境无关。
  2. 通过动态负载均衡改进的可伸缩性

    架 构允许系统以一种线性的方式扩展来满足计算资源日益增长的需求。额外的需求通常是由于同时在线玩家数量的增加、应用程序复杂性的增加或者两者同时发生引起 的。无论哪种方式引起的,考虑到游戏运行时的动态行为,面对增加的任务负载,该架构都自动地执行负载平衡来给与响应。当需要更多的容量时,简单地增加更多 的计算节点到可用的服务器池中。多个游戏甚至可以共享计算中心的服务器。在当今的游戏行业,现存架构是不可能完全实现这种资源共享和可伸缩性的。
  3. 为今后的计算技术而设计

    各主要芯片设计使用并行性技术,拥有性能改善功能。单芯片多线程虽然保存了能量,增大了吞吐量,扩展了摩尔定律,但是如果那些程序要想在硬件新阶段受益,就需要以不同的方式来编写。Darkstar 项目基础结构拥有性能改善功能,且不需要改变游戏代码本身。
  4. 健壮的游戏运作能力

    Darkstar 项 目系统基础结构的设计方便了大型多玩家在线游戏的开发,而且该游戏将比迄今为止该行业中的任何游戏都健壮。游戏服务器崩溃、数据库破坏和编程错误是很常 见的,为此,公司需要组织大型的内部开发者团队、网络专家和操作人员来维护游戏。这已经在需要绝对可靠性的金融和企业领域得到证实,我们相信由 Darkstar 项目创建的游戏将会更加健壮,维护和增强也更加简单,且不以牺牲交互游戏需要的性能为代价。这样,将会缩短开发周期(对于新游戏和新特性,从构思到市场所 需时间变得更短),减少开发成本,以及减少支持和运作成本。
  5. 有效利用计算资源

    Darkstar 项目是一个完整的游戏架构,也就是说其运作模型不需要将特定的硬件分配在特定的游戏区域。当游戏需要时,可用的服务器资源可以动态的进行再分配。使用 Darkstar 模型,您不会遇到碎片架构存在的限制,如在 Second Life 和 多数其他 MMO 这样的碎片架构中,一些服务器过载,而另一些服务器处于闲置状态。例如,公开的有用数据显示:Second Life 的特点在于当孤岛容量受到严重限制时,整个服务器仅仅使用了5% 或者更少。然而,他们却仍然一直在增加许多机器到他们的基础结构中,试图去跟上订阅者数量的增长。启用的 Darkstar 项目架构有更高的服务器利用率,这样节约了机器成本,同时也节约了支持基础结构和运作的成本。所以,成本完全减少了,这些成本可以有效地分配到跨单个游戏 或多个游戏的多协议栈上。在当今的游戏行业中,您还发现不了这种部署的灵活性和计算机资源的重用性。

1.1 多人游戏

    你对于多人在线游戏一定有着绝妙的创意。可能它是一个虚拟的世界,源自于你超级喜爱的电视节目中,或者它干脆就是一个你和你的朋友们拥有的在线保龄球联盟。无论如何,真正急待解决的问题在于,相对于奇思妙想来说,真正构建一个大型的多人在线网络游戏,它竟是如此的复杂,以致于许多具有天马行空的伟大创意最后却只能在历史的车轮中无奈地烟消云散。Darkstar解决了这个棘手的障碍,它提供了一组易于使用的功能库,帮助你处理网络游戏开发过程中所要面临的复杂的、充满挑战性的每个方面。此外,它还致力于提供一个健壮的、稳定的、可弹性伸缩的服务器。使用Darkstar,你可以很快地把你的美妙创意转变为实实在在的游戏。

    电脑游戏在过去的十年中取得的重大进展之一就是,多人在线网络游戏取得了爆炸式的发展。从大量的多人在线角色扮演游戏(MMORPG)创建了不计其数的虚拟世界(甚至是太阳系、宇宙……)让玩家去冒险,到人们可以通过网络互相进行国际象棋的对弈、玩扑克牌、或者其他传统的游戏,通过网络进行的方式广泛地影响了我们正在玩的游戏以及我们以及在游戏中的伙伴与对手们。多人游戏提供了无与伦比的体验,尽管人工智能(AI)可以做到很多事,但是与通过网络跟实实在在的人类对手进行互动和游戏相比,这样的挑战与获得的愉悦,是AI所无法复制和达到的。

    然而,尽管有着这样的历史,基于服务器的多人游戏到目前为止,也仅仅是许多游戏公司的部分业务而已。这在很大程度上是由于,与此相关的大量资源和专业技术,存在一个相当基础也是相当重要的壁垒----创建一个成功的并且健壮的多人网络游戏环境。你可能会有一个伟大的游戏构思,但是却并没有相关的专业技术来开发它,或者有足够的资源来支撑数以千计的蜂拥而至的游戏玩家。如果这时候,有人致力于这个困难的工作,并制作了一系列工具使得多人网络游戏更加容易地开发,这难道不是件很棒的事情么?而且,随着越来越多的游戏玩家进入到你的游戏中来,如果通过此工具制作的游戏能够更加容易更加快速地进行响应,不也是件很棒的事情么?Darkstar,一个针对多人在线游戏的应用服务器正是用来帮你实现这些愿望的,而且它其实能做更多的事。Darkstar让你从创建一个可以支持许许多多通过因特网加入到你的游戏中来的、一个企业级服务器解决方案的复杂任务中解放出来,取而代之的是,你可以专注于另一个非常重要(当然,也是非常有趣)的部分:创建更加出色的游戏体验!

    那么,Darkstar是怎么做到这些的呢?Darkstar是一个用来创建多人游戏的应用服务器。它为游戏的开发者们提供了一系列的功能函数库,这些库实现了开发一个多人游戏所需要的基础。同时它还提供了一个健壮的、高可靠性的、随着用户不断增长可弹性伸缩的应用服务器架构。本手册撰写的初衷,便是要探究Darkstar游戏服务器的细节,展示一些关于如何使用Darkstar创建结构完整的多人游戏的相关过程。

1.2 多人游戏的体系结构 

     乍一看,网络多人游戏貌似是一个极度复杂的软件系统。其实不然,事实上多人游戏就相当于一曲由许多相互有关连的简单组件有机组成的管弦乐曲罢了。本章将要讨论的是,一个针对多人游戏的通用的、高级的体系架构。虽然每个游戏的各自实现都会有些许不同,但是这个通用的框架提供了一个统一的体系,适用于理解多人网络游戏。本章描述了计算机游戏经典的客户端-服务器架构。尽管点对点(P2P)游戏已经成为了许多学术研究的课题,然而这些技术至今未得到广泛的应用,并且它们也不被Darkstar所支持,因此它们不在本手册的讨论范围内。

      多人网络游戏存在着不同层次的抽象。最高层的抽象概念即为客户端与服务器。每个客户端维护单独的游戏中各玩家间的交互信息。服务器作为所有客户端进行交互的中间媒介并且担当游戏的规则仲裁者的角色。在任何一个多人游戏中,都存在着许多不同的角色(即“多人游戏”中的“多人”)。每一个角色都至少对应着一个现实生活中的玩家,他们通过运行在他们电脑上的客户端应用,以键盘、手柄及鼠标等各种方式进行交互。这些客户端把各自的交互信息(即行为)轮询提交给所在网络中(本地网或Internet)的服务器。游戏服务器通过维护整个游戏世界中的当前的、完全的游戏状态来管理这个游戏。

      在游戏的单次轮询中,游戏服务器接收来自每个客户端的行为,并根据游戏规则对这些行为进行仲裁和应答,同时将游戏的状态更新返回给客户端。一收到新的游戏状态,客户端将立即显示它们同时准备接收新的用户行为。因此,一个游戏循环的基本算法流程是这样的:

1、 客户端连接服务器
2、 客户端 从服务器接收游戏状态
3、 客户端 向用户显示游戏状态
4、 客户端向服务器发送用户输入行为
5、 服务器接收客户端的行为,通过游戏规则处理后更新游戏状态
6、 服务器发送新的游戏状态给客户端
7、 重复步骤2-6,直到客户端断开连接


客户端具有四个基本的功能特性:


1、 用户输入
2、 向服务器发送用户行为
3、 接收来自服务器的游戏状态
4、 图形显示


服务器具有三个基本的功能特性:


1、 用户输入
2、 运行游戏逻辑
3、 广播游戏状态

      服务器在一个单独的逻辑位置来聚集游戏的信息并维护整个游戏的运行状态。这项特性最为关键的地方在于,它简化了来自客户端一系列动作所导致的游戏状态更新的相关过程。它同时也消除了客户端与服务器之间游戏状态可能存在不同步的隐患。因为作为仲裁者的游戏服务器总是正确的。这样的集中式管理也极大减少了客户端/玩家通过各种手段进行作弊的可能性。因为是游戏服务器来执行游戏的相关规则和逻辑的,它能确保每一个玩家都要服从于既定的规则之下。

1 .3 游戏的应用服务器 

    成功编写出多人游戏存在着各种各样的挑战。这些挑战可以简单地归纳为以下四个范畴:

1、通信
2、同步
3、数据的持久化
4、网络的可伸缩性

      前面两个部分包含了使一个多人游戏得以正常工作的基础细节。通信模块包括客户端和服务器两者之间的网络对话。同步处理模块涵盖了多个客户端同时进行访问以及修改那些被共享的游戏状态等相关的问题。后两个部分则主要解决实现一个健壮的、高可靠性的游戏涉及到的部分。数据持久化模块确保了游戏服务器即使在当机或崩溃的情况下也能够正常地保存和归档游戏世界的各种状态。弹性伸缩机制有助于你的游戏服务器在同时被数以千计的使用者访问时也能够保持稳定出色的表现。这些问题都是非常重要的且是难以正确有效地实现的。总之,他们经常被认为是阻碍个人开发者或小型团队实现他们的多人游戏的最大难题。并且,正确地实现网络通信和同步处理并不是真正有趣的部分。我们真正感兴趣的在于编写游戏!

      幸运的是,Darkstar正是为了游戏而设计的应用服务器。应用服务器的目的,是为了提供通用的、基础功能性的(一如前文提到的包含通信、同步、持久化和伸缩性的功能函数库)、健壮的、高效的和简单易用以便于使用者能把重心集中在实现对他们的应用的功能性特性上面(一如你的游戏!)。由Darkstar应用服务器提供的基础功能可以让个人开发者把重心集中在他们正在开发的游戏上面。Darkstar应用服务器可以帮助你在很短的时间内快速地开发一个健壮的多人在线游戏。此外,它还确保了你的程序在面对大量玩家的时候能够保持高度的伸缩性。

 Darkstar 游戏服务器支持下列的硬件/操作系统组合:

1、 Windows XP on 32-bit processors
2、 Mac OS X 10.4.x on PowerPC or Intel processors
3、 Red Hat/Fedora Core Linux on 32-bit x86 processor

     在一些平台(Windows和Linux)上。你可能需要安装或升级Java虚拟机(JVM)。Darkstar需要J2SE 5.0或更高的版本。在OSX或Solaris系统上已经正确安装了所需的JVM。如果你的JVM已经过期,你需要为你的游戏服务器下载一个新的版本。Darkstar的下载地址为http://www.projectdarkstar.com,它最近的一个版本是0.9.9。Darkstar以.zip文件的形式发布。下载完毕后,把它解压到你想要放置的目录下就完成了工作的一大半。安装游戏服务器的最后一个步骤是设定一个环境变量使其指向你的Darstar游戏服务器的位置。在Windows系统上,经过“控制面板”的“系统”选项卡创建一个名为“sgshome”的系统变量,将此变量的数值设定为游戏服务器所在目录。在Mac OS X 和Linux系统上你需要修改位于home目录中的.bashrc 文件,添加一行SGSHOME=location(即你的游戏服务器所在真实路径)。 完成到这一步的时候,意味着 Darkstar已经成功地被安装。然后就是开始编写你的第一个游戏的时候了!

游戏客户端与运行在Darkstar平台上的服务器端应用程序(拷贝)进行数据交互. 负载均衡和错误恢复均由Darkstar服务管理.

.....................................

Tasks and Managers 任务和管理者:

从PDS 应用开发者的角度来说,PDS 应用执行在一个封闭的单线程的,事件驱动模型中。通过句柄传递事件实现编码对数据的修改,对于编写代码的程序员来说就好像是在修改自己的数据一样。因此,执行程序是一个平稳竞争和弱死锁的。在大多数情况下,没有必要

通过的代码,事实上,在管理数据对象是经常使用synchronized 关键字容易产生不稳定的bug。

    事实上,这个系统有很多的线程用于控制异步的事件的处理。这些控制线程叫做任务。这个系统对每个任务的访问数据进行监视。当一个冲突升级时,一个任务正在执行,计划任务会在之后重新尝试执行,这样任务就可以竞争,并且脱离死锁的危险。任务创建PDS 的关系者。一个PDS 应用的通过管理器来影响PDS环境和外部世界的操作。在系统中一共有三种标准的管理者。实际上,外加的管理者可以通过编码添加到PDS 环境中。标准的管理者如下:

(1)       Task Manager 任务管理者

一个PDS 应用可以使用任务管理者排列其自己的任务。任务可以被分为立即执行任务,延迟执行,空闲时间执行。在没有其他任务条用任务的时候任务创建。排列子任务的任务叫做父任务。多个子任务被同一个父任务排列执行,成为兄弟任务。

(2)       Data Manager 数据管理者

PDS 应用可以使用数据管理这创建和访问持久化数据,生成的Java 对象叫做管理对象。PDS应用是由其自己生成的一个管理对象。PDS 应用由管理对象组成,这个在下面的“管理对象和管理关系”中已经全面的解释了。

(3)       Channel Manager 通道管理者

PDS 应用可以使用通道管理者创建和控制发布/订阅模型的数据,这些数据通道用于在客户端的组和服务器间进行通信。

一个PDS 应用可以通过应用程序的上下文访问核心的PDS 方法,这个上下文提供了联系多个管理者的关系和方法。

 

 

Task Ordering 任务顺序

任务(管理器)由客户端触发的事件在PDS系统中是按顺序执行的。由同一个客户端产生的比较早到达的事件完成之前,任务管理器不会立即执行相同客户端传递来的事件(而是会等待前面的事件处理完成之后才会再执行后面的事件)。一个子任务执行的顺序是依赖于其父任务,而不是根据其自己的处理顺序。这就意味着在父任务未完成之前,子任务是不会开始执行的。

要点:在系统中没有其他的顺序。特别的,不同用户的任务事件开始执行的顺序与他们到达服务器的顺序有关系。

Task Lifetime 任务的的生命周期

任务应该是一个生命周期比较短的,这样就不会发生访问的阻塞,当一个资源需要花费大量的时间时,它就应该由其他的任务来完成。PDS系统设置了一个任务的执行的最大时间(默认值是100毫秒).任何在这个时间内没有完成的任务都会被终止。如果你有一个任务运行的时间很长,有两种办法来解决它的执行时间问题:将其拆分成多个链式的子任务,每个Handler处理这个问题的一个操作,并将下一个要执行的任务放在要执行任务的队列中。这个就是注明的状态机模式。将比较耗时的计算移动到一个自定义的管理器中,当计算完成时会返回一个结果。每种方式都有其有利或不利的地方。第一种方式用于解决比较简单的问题,但会使他们陷入严重的困扰之中。要仔细的检查在每个任务在结束时的状态,因为没有正确的执行顺序,用于指明下一步要怎样操作。一个特殊的情况是,这个问题的哪个部分被拆分并平行的分离出来。在这种情况下,完成这个任务的时间会因为链上的任务时间会减少。然而这些平行的任务连,彼此之间没有顺序,所以处理他们的工作的线程也是彼此独立的。第二个阶段对与服务来说比较简单,他们没有被完整的分成小的不相关的组件;然而,他需要自己写一个PDS 的管理者,并且安装到PDS 环境中。(关于写一个自定义的PDS管理器的方法已经单独的在《怎样扩展PDS系统》的文档中单独的说明了。)一个特别重要的情况是编写一些需要条用系统模块,并且需要消耗执行时间的一些方法。他们需要自定义一个管理器,这样就降低了PDS应用的健壮性。这也暗示了那些有两个不同客户端生成的任务不需要按他们客户端的生成顺序来执行。实际上,这在网络游戏中是不正确的,除非指定一个特定的程序让它这样的执行,因为在两个客户端通信的时,这些简单可变的信息对于服务器来说是按顺序到达的。

Managed Objects and Managed References 管理对象和管理关系

数据管理对象主要是一个持久化对象的集合,存储在一个叫做对象仓库的池中。和一个正常的Java对象一样,每个对象都包含一个方法和其自己的数据。要成为一个管理对象,这个对象就要实现ManagedObject(管理对象的接口)和Serializable(序列化接口)。一个管理对象不会成为一个对象存储仓库池中的一部分。直到这个池检测到这个对象是这个池中的一部分。

这个是通过数据管理者或者是向这个对象请求一个数据管理关系或者是给这个对想绑定一个名字。一个管理关系对象就像J2SE中的关系对象一样(例如:软件关系,弱关系)。管理的对象要和其他的管理对像通过管理管理来建立联系。这就是数据管理对象可以通过一个关系通知不同的组件对象的对象管理者,(该数据)是这个管理对象状态的一部分,一个关系和一个独立的管理对象通过器自身的状态来(建立关系)。通过一个用字符串绑定的名字到管理对象,这样,这个对象就可以被其他的任务通过数据管理者调用getBinging 的方法从对象仓库中将该对象取出。访问管理对象要通过管理关系。

这个管理关系有两种访问方法:get和getForUpdate。每个方法都返回这个任务本地的一个对象的拷贝。他们的不同之处在于:getForUpdate通知系统你的目的是要修改管理对象的状态。Get通知系统你的目的只是读取该对象而不是对其进行写操作。虽然对于任何管理管理对象的操作都是持久的(即使他们是通过get方法),如果在某时刻你想要去改变这个管理对象的状态,使用getForUpdate方法更好一点。这允许系统检测在任务间的冲突,并尽早、尽快的解决掉这些冲突。相反,如果你没有改变管理对象的状态,使用get 方法更好一些。Get方法允许更多的来自于不同任务的平行的访问操作。当你在执行程序的某个时候,你知道你将改变管理对象的状态,你可以通过调用markForUpdate方法来标记数据管理者geForUpdate 方法来更新你的访问操作。(多个调用来标记同一个访问对象是有害的。) 同一任务的子任务序列通过get和getForUpdate 使用相同的管理关系得到的管理对象是同

样的一个本地(管理对象)的副本。你也可以通过一个对象绑定的名字调用getBinding 方法来获取该对象。这个和使用管理关系来调用get 方法得到的对象是相同的,所以你要修改一个对象的状态时,你需要在反转了这个对象以后调用markForUpdate 方法。

在对象仓库中的管理对象是不会被垃圾回收的。一旦这个仓库有了一个管理对象,仓库就会一直保存该对象的状态,直到有(任务)使用数据管理者里调用removeObject 方法,该对象才会被删除。这需要应用程序来管理管理对象的生命周期,当它们不再需要该对象的时候就将该对象从对象仓库中删除。如果这样的操作失败,将会导致垃圾处理器来回收你的对象仓库,(这样也会)降低系统的性能。同样的,绑定的名字也会被存储,直到它(绑定的名字)被确认已经通过removebinding 删除。当有引用只想该对象时,这个绑定的名字不会被删除。要知道这些将会在字节码或者是PDS 的API 中本身中。请参考文档末尾最好的一个实践,来获取更多的信息。

 

设计你自己的管理对象

管理对象分为三种基本类型:

(1)在你游戏虚拟环境中的活动对象,例如一把剑,一个怪,或者一个游戏场景(比如一个房间)。(2)纯逻辑或数据结构,例如一个方块树,用于检测玩家周围的环境或者一条路径用于检测玩家的运动路径。(3)在世界中用于模拟玩家(信息)的管理对象。

下面展示了一个基本的世界,它由一个房子,里面有两个玩家和一把剑。

 

怎样决定在哪里将数据分成多个数据管理对象,这和这些的问题有关:

u       这个数据有多大?单个管理对象在其内部存储的状态越多,用于保存和加载信息的时间就越多。

u       这些数据的联系有多紧密?经常要在一起访问的数据放在一个管理对象中会更有利。数据若单独被访问,应该拆分成多个管理对象。若数据要被自动的修改,最好放在同一个管理对象上。

u       有多少任务需要同时访问这个数据?就如上面所说的,PDS会尽可能多的执行并行的任务。解决多个需要改变同一个管理对象的平行任务的冲突花费的代价是昂贵的。最好的方式是将数据进行分割,并且对于更新操作是锁定的(即不能更新),并且可以让get方法共享该数据。数据要进行更新时必须要拥有一个专门的跟新数据的任务,这样数据就可以被多个读的任务所共享。当多个任务需要访问一个管理对象的区域,并且这个区域至少被它们其中的一个任务所修改,那么这个对象就有可能发生阻塞。为了达到最好的性能,你要尽可能少的有发生阻塞的管理对象。

在上面所有的条件中,第三个条件对一个良好运行的PDS 应用来说是最有挑战性的。

The Player Managed Object 玩家的管理对象

管理对象通过一个管理者将其自身注册为一个事件句柄,当有外部事件触发时,该管理对象相应的事件句柄会被调用。一个非常重要的管理对象类型就是玩家的管理对象。一个玩家的管理对戏那个实现了一个ClientSessionListener(客户端会话监听器)接口,并且会作为AppListener程序监听器的登陆信息的返回信息的类型返回到系统。到此,它将可以被任何进入到系统的数据包调用,并且从玩家管理对象将对应的事件删除。

对于世界中的玩家对象来说,玩家管理对象扮演了一个代理角色。玩家通过PDS 客户端的API 发送一个数据包到PDS 服务器。这样在服务器端会触发一个用户数据接收(UserDataReceiving)的方法。玩家的管理对象需要解析这个数据包,找出这个数据包发送的目的,并且扮演其自己和其他的管理对象来完成请求的任务。图片2 给我们展示了一个简单的管理对象的世界,有两个客户端连接到了PDS服务器。玩家管理对象有一个“当前房间”的范围,该范围是一个管理关系,该关系指向房间的管理对象。当前在这个列表中有三个例子:两个玩家和一把剑。每一个对象都提供了一个管理对象。(玩家1 的管理对象,玩家2 的管理对象和剑的管理对象)。

 


The AppListener 应用程序监听器

上面我们已经有了一个世界的管理对象,它由一个房间管理对象,一个剑的管理对象和一对玩家的管理对象。然而我们第一次开始这个游戏的时候,世界的管理对象并不是像这样的。实际上它和下面一样:这展示了什么,这是一个空的。怎样在玩家第一登陆的时候将管理对象存放到对象仓库中呢?答案是通过一个特定的管理对象调用AppListener(应用程序监听器),在这个AppListener(应用程序监听器)中定义了两种指定的操作,它实现了一个应用程序监听接口。这个接口定义了两个方法:initialize、loggedIn。它已经被指定为这个应用一个应用程序监听器。这两个属性按下面的方式结合在一起:

l         通过PDS 系统本身,PDS 在对象仓库将应用程序监听器本地化为一个应用程序的对象。

l         如果应用从来没有被启动过,那么这个对象在对象仓库中就是一个空的值(如图3 所示),PDS查找这个应用程序监听器的时候就会失败。在这种情况下,它自己会创建一个管理对象的应用程序监听器,然后移动一个任务,这个任务称为初始化。

l         如果,相反,这个应用至少被启动了一次,这个对象仓库已经包含了这个应用程序监听器的管理对象。在这种情况下,执行程序只是其上次推出的地方即系统退出时,监听新的连接并且执行在此前它已经执行过的任何周期性的任务。在这种情况下我们简单的示例应用,这个启动的方法将会发生阻塞,用伪码表示如下:

initialize {

CREATE ROOM MANAGED OBJECT

CREATE SWORD MANAGED OBJECT

ADD REF TO SWORD MANAGED OBJECT TO ROOM'S INVENTORY

SAVE A MANAGED OBJECT REF TO ROOM FOR LATER

}

通常,在第一次启时,创建世界中初始化的管理对象是应用程序监听器的责任。


现在我们有些东西已经开始像我们在我们游戏中所看到的那样了。然而,我们仍然没有玩家对象管理对象。当玩家进入时我们创建一个玩家管理对象,这个和应用程序监听器管理对象的创建方式是一样的。当我们看到玩家第一次登陆到服务器的时候,我们为用户创建一个新的玩家管理对象。之后,用户每次登陆,我们只要重新连接他或者她已经存在的角色管理对象就可以了。然而,系统是按需要创建一个玩家管理对象的,并在其登陆期间(在线时)记录用户的信息。所有我们应该怎样找出用户是何时登陆的呢?

答案就是第二次调用我们的应用程序监听器:LoggerIn。每次一个用户到PDS 系统的日志,一个任务开始时就调用在应用程序监听器中登陆的方法。当登陆的返回信息被我们的应用程序监听器调用时,它执行下面的代码,用伪代码展示如下。

loggedIn {

managedObject_name = “player_”+ SESSION.PLAYER_NAME;

IF MANAGED OBJECT EXISTS(managedObject_name)

{

FIND MANAGED OBJECT(managedObject_name);

} ELSE

{

CREATE NAMED PLAYER MANAGED OBJECT(managedObject_name);

}

SET currentRoom on PLAYER MANAGED OBJECT

TO SAVED MANAGED OBJECT REF TO ROOM

GET ROOM MANAGED OBJECT

ADD PLAYER REF TO ROOM MANAGED OBJECT'S PLAYERS LIST

REGISTER PLAYER MANAGED OBJECT AS SessionListener(SESSION);

}

ClientSessionListener 是另外一个事件接口。它定义了一个方法用于调用任务响应客户端的请求事件。例如发送一个数据到服务器用于处理客户端退出的事件。


 

 

图片5 展示了我们的对象管理世界开始变得和我们想的一样了。

当第二个用户登陆时,我们将回到我们原始的世界。图片6 展示了我们世界在重启游戏服务器后我们原始的玩家:

 

 

 

到此,逻辑部分已经用伪码展示了。这个应用事实上的源码的实现在附录A 中的SwordWorld的应用中已经给出。实际的应用的代码有点复杂,因为它也实现了一个显示窗口,显示给你玩家管理对象是怎样处理客户端发送的数据的。


Sun公司开源游戏服务器Project Darkstar Server——(Sun game server , 简称 sgs)学习笔记(一):sgs简介 - 木瓜网络 - 博客园 sql server 2005学习笔记之触发器简介1 sql server 2005学习笔记之触发器简介 【SGS】检测 白善烨(Paik Sun Yap) SQL Server Reporting Services(简称SSRS)-sql ser... SQL SERVER 存储过程学习笔记 SQL Server 2008 R2 群集(一) 《Microsoft SQL Server 2008 Analysis Services Step by Step》学习笔记二 - 邀月工作室 - 博客园 《Microsoft SQL Server 2008 Analysis Services Step by Step》学习笔记三 - 邀月工作室 - 博客园 高效学习十方法 - 1960sun的日志 - 网易博客 SQL Server 2000简介 Tuxedo 和WebLogic Server(简称WLS)间的集群配置 - ourang... MS SQL Server备份与恢复实例 - ?Ronli笔记 - 博客园 SQL Server 索引结构及其使用(一) SQL SERVER事务处理(七) SUN主机磁带库(Legato管理)的配置过程 morning sun SQL Server 2008中的代码安全(三):通过PassPhrase加密 - 邀月工作室 - 博客园 SQL Server 2008中的代码安全(四):主密钥 - 邀月工作室 - 博客园 SQL Server 2008中的代码安全(六):对称密钥加密 - 邀月工作室 - 博客园 SQL Server 2008中的代码安全(七):证书加密 - 邀月工作室 - 博客园 学习方法 转 如何成为学习上的第一名 - 1960sun的日志 - 网易博客 学习方法 转 养成良好的学习习惯 - 1960sun的日志 - 网易博客