Sun公司开源游戏服务器Project Darkstar Server——(Sun game server , 简称 sgs)学习笔记(五)
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 的管理对象和剑的管理对象)。