Berserker的沉默

导航

[SmartFoxServer概述]Zones和Rooms结构

ZonesRooms结构:

相对于SFS 1.X而言,在ZonesRooms的配置上,SFS2X有了显著的改善。尤其是我们建立了房组这样一个简单的概念,它允许在一个逻辑组中管理Rooms,从而独立于其他RoomsUsers可以订阅发生在该组中他们只感兴趣的事件,而忽略其他所有的。

这种方法的好处是通过服务器发送的初始room列表将会更小,并且对于发送到每个客户端的事件数量也会大幅度减少,特别是在一些高流量的应用程序中。

概念说明示例:

User可以订阅最初的Room群消息和接收Room的升级消息(例如最新创建的Room或者移除RoomUser数量的改变和Room变量升级等),不过这些都是限定于当前的Room群环境下。如果User有兴趣玩游戏,他可以选择订阅任何一个游戏群组,然后查看哪个游戏在运行再选择加入。User也可以随时订阅任一群组的消息,同样也可以拒绝订阅。即使他们不会再接收他们不在的Room任何更新消息,不过他们依然可以加入Zone中的任意一个Room

最新的方法是将ZoneRoom配置更进一步相结合,允许程序设计人员可以创建多群组,游戏,个人Room,私人领域等高度复杂的系统。最新特点同时包含了一套更合理和更具组织性的方式来管理Zone中的所有Room的同时,最低限度地保持客户端更新量。

下表描述了一些不同的可能情况:

·User在没有订阅任何Room组消息的情况下加入到Zone中:

在这种情况下,User将会收到一个空的room列表,同时不能通过服务器对Room事件进行更新。如果你想让user在不接收他们不需要的Room更新的情况下,与你的服务端扩展模块进行交互的话,可以考虑这种设定。常见的使用情况有:用户注册窗口,咨询一个用户搜索功能或者其他在不需要与其他客户端交互的地方与用户相关的动作。

·User加入到Zone中并订阅了一个Room群:

这个可能是最常见的使用情况,对于SFS1.X更是如此。而在这里的不同之处是,room列表只包含群中选中的room,从而过滤掉其他。客户端会默认更新最新创建的或者移除的room。开发人员也可以配置其他事件,例如更新user数量,room变量等级等。

·User加入到Zone中并订阅了多个Room群:

订阅多个群需要进行更复杂的Room过滤。玩家可以通过群中选定的Room获取自定义的room列表。通常情况下,客户端可以加入到群中,可能是一个特定主题的聊天群和一个玩家玩游戏的游戏群。

最后,群组可以在运行过程中创建,并且可以执行动态订阅/取消订阅。

详尽的Zone和Room事件:

通过SFS2X,你可以更好地控制每个ZoneRoom的事件。以下是在Administration Tool中的Room配置窗口。

上面的窗口告诉你,当你创建了一个新的Room,如何设置好Room级别事件和权限。根据以上的配置,users可以改变Room的名称和密码,同时可以禁止重设大小(改变容量)。公共消息也可以在Room和所有可用事件中进行发布。

在其他的Room中,你可能想设定不同的配置,禁止一些事件和提供一套不同的权限。

Room定义了两类设定:权限(Permissions)和事件(Events)。

权限(Permissions)表明了在运行过程中可执行的相关Room操作。

##ROOM_NAME_CHANGE:在运行过程中是否可以改变Room名称

##PASSWORD_STATE_CHANGE:在运行过程中Room密码是否可以改变

##PUBLIC_MESSAGESRoom是否支持发布公共消息

##CAPACITY_CHANGE:在运行过程中Room的容量是否可以改变

事件(Events)表明了客户端加入到Room中所触发的事件。

##USER_ENTER_EVENT:当user加入到Room中是否发送更新消息

##USER_EXIT_EVENT:当user离开Room时是否发送更新消息

##USER_COUNT_CHANGE_EVENT:是否需要每次Room里的user数量发生改变时触发事件

##USER_VARIABLES_UPDATE_EVENT:当user设置其User变量时是否发送更新消息

最后,Room有一种新的去除模式定义方法,该方法表明了是否需要或者什么时候需要自动移除Room。具体设置如下:

#Default:根据在SFS1.x定义的默认规则移除Room

#When_Empty:当Room为空时移除Room

#When_Empty_And_Creator_Is_Gone:当Room为空和创建者离线时,移除Room

#Never_RemoveRoom不允许自动移除。

User数量更新:

SFS中最消耗带宽的更新就是User数量更新事件,每次所有Roomuser数量改变了,它都需要向所有的user发送消息。在高峰期中该事件每秒会被触发几十次,导致带宽消耗和消息丢失的问题。

SFS2X中加入了引擎级的优化,最大程度上减少了user数量更新的影响。

#报文优先级:SFS2X引擎可以对每个低优先级响应的报文指定优先级别,例如当客户端消息队列繁忙时,User数量更新请求将被丢弃。当客户端使用慢连接时,可以显著减少消息丢失的问题。

#User数量更新节流:为了进一步增加对这一事件的控制程度,SFS2X可以在配置上设置为减速的速度,这样就可以将消息收集起来后选择最重要的一条消息进行发送。换言之,你可以在该事件被触发后指定一个特定的时间间隔。在该时间间隔中所作的更新会集中最新的消息,摒弃掉旧消息。

为了让你更清楚节流系统如何运行,我们假设时间间隔为2000毫秒。以下是在时间间隔中发生的改变:

 

以下是在下一个时间间隔真正发送的更新:

只有最新user数的数据得到了更新,而其他的被过滤了。

Room变量和User变量:

SFS2XRoom/User变量方面作出了很大的改善,在客户端和服务端两端增加更多的灵活性。

其中反映最多的增强是支持嵌套对象,我们已经补充说了。在数组和字典两方面都充分支持了。而我们也添加了下面的两种新的设定:

#隐藏:当Room/User变量被隐藏,它将不会发送至客户端。这便可以判定,哪个变量只属于服务端,哪个变量与客户端保持同步。新特点在保持自定义数据上不再需要用两种不同方法连接到一个Room/User对象,在之前的SFS1.x中你必须使用Room/User变量和Room/User属性,在SFS2X上,所有自定义的数据都通过Room/User变量来处理。

#全局:这是Room变量的属性。全局Room变量在Zone层更新,换言之,也就是在Room外更新。这意味着设为全局属性的Room变量会在同一个Room群中的所有客户端作出更新。这是要求多次,期待许久的特点了。

下面是在Extension中设置Room变量的快速例子:

 1 private void setSomeVariables(Room room, User owner)
 2 {
 3     List<RoomVariable> listOfVars = new ArrayList<RoomVariable>();
 4     listOfVars.add( new SFSRoomVariable("bgImage", "coolBackground.jpg") );
 5     listOfVars.add( new SFSRoomVariable("stars", 4) );
 6      
 7     RoomVariable hiddenVar = new SFSRoomVariable("isPremiumUsersOnly", true);
 8     hiddenVar.setHidden(true);
 9     listOfVars.add(hiddenVar);
10      
11     // Set variables
12     sfsApi.setRoomVariables(owner, room, listOfVars)
13 }   

正如你所见,hiddenVarRoom变量被设置为hidden,它将不会发送到客户端。服务端的代码将会检测该变量,查看该Room是不是只属于付费用户。

在客户端(AS3),设置该变量也同样简单。

 1 private function setSomeVariables(room:Room):void
 2 {
 3     var listOfVars:Array = new Array()
 4   
 5     listOfVars.push( new SFSRoomVariable("bgImage", "coolBackground.jpg") )
 6     listOfVars.push( new SFSRoomVariable("stars", 4) )
 7   
 8     // nested object
 9     var chatSettings:SFSObject = new SFSObject()
10     chatSettings.putUtfStringArray("allowedFonts", ["Verdana", "Arial", "Times New Roman"])
11     chatSettings.putIntArray("allowedFontSizes", [10,11,12,13])
12     chatSettings.putBool("isBoldAllowed", true)
13     chatSettings.putBool("isItalicAllowed", true)
14     chatSettings.putBool("isUnderlineAllowed", false)
15      
16     listOfVars.push( new SFSRoomVariable("settings", chatSettings))
17      
18     // Set variables
19     sfs.send( new SetRoomVariablesRequest(listOfVars, room) )
20 }

 

posted on 2014-02-20 00:14  Berserker的沉默  阅读(1803)  评论(0编辑  收藏  举报