本文介绍ESFramework 开发手册(00) -- 概述一文中提到的ESPlus的两翼:好友关系与组关系。
大部分分布式通信系统中,除了客户端与服务器进行通信外,都还会涉及到客户端之间相互通信、以及需要将客户端进行分组的功能,或者是类似这方面的需求。ESFramework对这一常见的任务内置了强大的支持,包括从客户端到服务端、一直到ESPlatform群集。在设计时,我们就考虑到了如何对常见的好友通信与组广播通信进行最大的支持,以期让ESFramework的使用者非常容易的就能够使用这些功能。
在ESFramework中,好友与组成员并不仅仅是指用户(某人),而是指任何一个运行的客户端实例。只要两个客户端实例之间需要频繁相互通信,那么它们就可以建立好友关系(friend)。如果需要在某些特定的客户端实例间进行广播通信,那么这些实例就可以被划分到同一个组,成为组友(groupmate)。如果是使用ESFramework开发类似IM的系统,那么这两种关系就更明显,它们就类似QQ的好友与群。
ESPlus定义了好友管理和组管理的接口(IFriendManager与IGroupManager),如果你的应用需要好友与组方面的功能,那么只要实现这两个接口,并注入到框架中,就可以拥有ESFramework内置的好友与组方面的强大功能了。但是,如果你的应用中仅仅是客户端与服务器进行通信,不需要好友与组方面的功能,那么,你就可以直接使用框架内置的null object模式的EmptyFriendManager和EmptyGroupManager作为占位符对象。
ESFramework 并不会强制性地要求你的应用必须要实现一个与自己的项目需求没有任何关系的接口(比如IFriendManager与IGroupManager)。我们将选择的权利交到了你的手中,你可以根据项目的具体需求,决定要实现哪些接口,并注入到ESFramework框架中。甚至,你可以只实现IFriendManager和使用EmptyGroupManager;或者反过来,只实现IGroupManager和使用EmptyFriendManager。要如何做,完全取决于你的项目要求。
ESFramework 内置了最简单的好友管理接口ESPlus.Core.Server.IFriendManager,其定义如下:
GetFriendList方法用于获取某个用户的所有好友的UserID列表。同很多常见的返回集合的方法设计规则一样,该方法不允许返回null,如果目标用户没有任何好友,那么请返回元素个数为0的List。
当某个用户的好友发生变化时(比如,增加或移除好友),则应该触发FriendChanged事件,以通知ESFramework框架。特别是在ESPlatform群集平台中,各种类型的应用服务器将会按情况缓存部分好友列表,当框架接收到FriendChanged通知时,可以删除或更新已过期的缓存。如果是简单的应用,而且也不需要使用ESPlatform,那么在实现IFriendManager接口时,可以忽略FriendChanged事件。
接下来我们看,有了IFriendManager这个接口,框架可以提供哪些与好友相关的功能或特性。
有了这两组特性的支持,每个运行的客户端实例,在其运行的整个生命周期中,都可以清楚地知道每个好友的在线状态。在具体项目中,我们可以这么做,当某个客户端登陆成功后,就获取所有好友列表和所有的在线好友列表,并预定IBasicOutter的FriendConnected和FriendOffline事件,然后在运行的过程中,当FriendConnected和FriendOffline事件触发时,就修改对应好友的状态。这样就保证我们的客户端可以实时地知道每个好友是否在线。
ESFramework 内置了IFriendManager接口的两个实现,一个就是上面提到的占位符EmptyFriendManager,还有一个是DefaultFriendManager。
组管理比好友管理稍微复杂一些,其复杂是因为一个用户可以加入到多个组,而且不同的组的成员是可以重复的。ESFramework内置了最简单的组管理接口ESPlus.Core.Server.IGroupManager,其定义如下:
接下来我们看,有了IGroupManager这个接口,框架可以提供哪些与组相关的功能或特性。
同IFriendManager一样,有了前两个特性的支持,每个运行的客户端实例,在其运行的整个生命周期中,就可以清楚地知道每个组友的在线状态了。n
ESFramework 内置了IGroupManager接口的一个实现,就是前面提到的占位符EmptyGroupManager,它对接口的三个方法的实现都是返回元素个数为0的列表。
如果具体的项目中需要频繁地用到好友与组等特性,那么在实现IFriendManager接口和IGroupManager接口时,要特别注意性能问题。
因为IFriendManager接口和IGroupManager接口的方法会被框架频繁调用,所以,必须想办法提高IFriendManager和IGroupManager接口的实现的性能。
如果IFriendManager和IGroupManager接口的方法被调用时,每次都需要从外部介质(比如DB、文件等)重新加载好友关系与组关系,那么毫无疑问将严重地降低应用程序的性能。通常的解决方案是,使用缓存避免重复读取。当好友关系与组关系没有发生变化时,直接从内存返回对应的列表。(在ESPlatform群集平台中,三种类型的应用服务器AS、BS、TS都针对好友和组内置了延迟加载机制和缓存机制)。
至于究竟采用何种策略来提升IFriendManager和IGroupManager的性能,需要根据你的项目具体情况而作妥当设计。特别是在高性能的分布式通信系统中,这一点是万万不可忽视的。
IFriendManager和IGroupManager返回的好友列表和组友列表,请尽可能的精简,不要包含垃圾数据。特别是当服务端引擎的FriendNotifyEnabled和GroupNotifyEnabled属性(将在后面介绍)设置为true时,用户的状态变化会自动通知其所有好友和组友。如果用户状态改变频繁,而其好友和组友数量又很巨大时,这种开销是非常大的。必要时,可以考虑将FriendNotifyEnabled或GroupNotifyEnabled设置为false以关闭状态改变自动通知。
下一篇文章,我们将介绍分别用于服务端和客户端的Rapid引擎,敬请关注,谢谢。
-----------------------------------------------------------------------------------------------------------------------------------------------
关于ESFramework的任何问题,欢迎联系我们:
电话:027-87638960
Q Q:372841921