ESFramework 4.0 快速上手(06) -- Rapid引擎(续)

  《ESFramework 4.0 快速上手》系列介绍的都是如何使用Rapid引擎(快速引擎) -- RapidServerEngine 和 RapidPassiveEngine。其实,大家可以将这两个引擎看作是两个壳,内部包装的才是真正的ESFramework的网络引擎, ESFramework支持很多种网络引擎(客户端/服务端、二进制协议/文本协议、TCP/UDP),而RapidServerEngine和RapidPassiveEngine采用的是基于TCP和二进制协议的服务端引擎和客户端引擎。这两个壳存在的目的,就是使大家不用了解ESFramework内部机制,就可以非常快速的上手ESFramework应用开发。但是,限制也是有的,那就是Rapid引擎仅仅使用了ESFramework最基础的功能,还有很多重要的功能,就不好通过Rapid引擎体现出来了。当然,通过复杂的封装,也可以做到全部体现,但是那样的话,Rapid引擎的上手就不是那么容易了,Rapid就不"Rapid"了。

  尽管如此,对于一些简单的应用,Rapid引擎已经足够应付了。在这里,我再补充一些为了更好地使用Rapid引擎时需要了解的一些信息。

 

1. 对称性

      ESPlus.Application命名空间下的组件用于协助我们快速地开发ESFramework应用程序,并且对服务端和客户端都提供了支持。比如,对于上面提到的自定义信息的支持,就是ESPlus.Application.CustomizeInfo命名空间做的事情,其下包含两个子命名空间:ESPlus.Application.CustomizeInfo.Server和ESPlus.Application.CustomizeInfo.Passive,分别用于服务端和客户端。

  你可能已经注意到,像 ESPlus.Application.xxxxxx.Server 和 ESPlus.Application.xxxxxx.Passive 通常是成对出现的,都是为了解决xxxxxx问题而对服务端和客户端的支持。而且,这种成对的关系也不会出现错误的匹配,比如,服务端调用ESPlus.Application.Basic.Server下的IBasicController的Broadcast方法进行广播(对所有人),一定是由ESPlus.Application.Basic.Passive下的IBasicBusinessHandler接口的HandleBroadcastFromServer方法来处理,而不会错乱匹配到由ESPlus.Application.CustomizeInfo.Passive空间下的ICustomizeInfoBusinessHandler接口的HandleBroadcastFromServer方法(用于处理组内广播)来处理。

     

2. Rapid引擎仅仅使用了ESPlus.Application下的两个命名空间

      Rapid引擎主要使用了ESPlus.Application.Basic和ESPlus.Application.CustomizeInfo命名空间下的组件。如果要使用ESPlus.Application下的其它命名空间中的组件(如ESPlus.Application.FileTransfering命名空间用于文件传输),那么就不能使用Rapid引擎这个壳了,必须使用ESFramework 4.0 概述中列出的那些真正的网络引擎。 

 

3. Rapid引擎中简单的好友管理和组管理

      IRapidServerEngine的Initialize方法有个稍微复杂的重载,即多接受IFriendsManager和IGroupManager两个参数,我稍微解释一下这两个参数的作用。

(1)IFriendsManager是给ESPlus.Application.Basic.Server下的组件用的,当某用户上下线时,需要通知该用户的好友(通过ESPlus.Application.Basic.Passive.IBasicBusinessHandler接口的相关方法),那么服务端从哪里知道该用户有哪些好友了,就是IFriendsManager接口:

    public interface IFriendsManager
    {
        List<string> GetFriendList(string ownerID);

    }

      如果,调用RapidServerEngine的Initialize方法时,该参数传入null,则RapidServerEngine会自动使用DefaultFriendsManager,这个实现的假设是所有的在线用户都是好友 -- 所以,任何一个用户上下线,都会通知所有其他的在线用户。

(2)IGroupManager接口是给ESPlus.Application.CustomizeInfo.Server命名空间下的组件用的,当客户端或服务端需要在某个组内广播消息时,服务端需要根据groupID获取该组的成员,这就是通过IGroupManager接口来获取的:

    public interface IGroupManager
    {
        /// <summary>
        /// 获取某个组的所有成员列表。
        /// </summary>      
        List<string> GetMemberList(string groupID);
    }

      如果在服务端Rapid引擎初始化时,该参数传入null,则RapidServerEngine会自动使用EmptyGroupManager,其GetMemberList方法将始终返回一个空的列表。如果需要用到组广播的功能,大家可以自己实现这个简单的接口,然后注入给服务端的Rapid引擎就行了。

(3)有很多朋友问到,如何添加好友,或如何创建组、或如何加入到某个组?这些都是由您的应用来决定的,ESFramework并没有任何限制。比如,ESFramework使用IGroupManager接口的目的仅仅是为了内置组内广播消息这一基本功能,所以,ESFramework对IGroupManager的定义非常简单,你的应用只要实现IGroupManager接口,就可以直接使用框架内置的广播功能了。

      好,现在我们假设,你的项目需要类似QQ的加入群(组)的功能,那该怎么做了?其实您可以这样设计:定义一个请求加入组的自定义信息类型(比如1300),信息内容中包含了要加入群的号码;再定义一个加入组的回复的信息类型(比如1301),信息内容中包含了加入成功还是失败的结果。那么,在需要加入组的时候,客户端就发送类型为1300的信息给服务器,服务器收到并处理该消息后(比如可以将组关系保存到DB),返回类型为1301的消息给客户端,客户端收到1301类型的消息后,就可以UI上通知用户。具体的例子可以参见这篇文章。这样就实现了加入组的项目需求。类似,创建组、加好友、删除好友等需求都可以采用类似的做法,这些只要使用ESPlus提供的自定义信息功能就可以做到。如果你对自定义信息的使用还不是很熟悉,那么可以参考ESFramework 4.0 快速上手 -- 如何使用自定义消息?

     关于ESFramework中好友与组更全面的描述,请参见ESFramework 4.0 进阶(11)-- 好友与组。 

 

4.UserID的长度

      在ESFramework 4.0 进阶(01)-- 消息一文中我们介绍了ESPlus提供了默认的消息头实现,而Rapid引擎使用的就是ESPlus提供的基于二进制的消息头StreamMessageHeader,这个消息头的默认长度是36字节,允许的UserID最大长度为11字节。但是,如果你的系统中需要用到的UserID长度超过了11字节,该怎么办了?我们可以通过调用StreamMessageHeader的SetMaxLengthOfUserID静态方法来设定ESFramework允许的UserID的最大长度:

        /// <summary>
        /// 设置UserID(包括GroupID)的最大长度(不能超过255)。注意,客户端与服务端要统一设置。
        /// </summary>  
        public static void SetMaxLengthOfUserID(byte maxLen)

      注意,我们必须在Rapid引擎的Initialize方法执行之前调用SetMaxLengthOfUserID方法。而且,客户端和服务端必须采用相同的设置,否则,就一定会导致服务端和客户端通信出现异常。如果你的客户端是使用的Silverlight,那么使用ESFramework.SL时也是如此。

(1)服务端和桌面客户端请调用ESPlus.Core.StreamMessageHeader的SetMaxLengthOfUserID方法进行设置。

(2)Silverlight的客户端请调用ESFramework.SL.StreamMessageHeader的SetMaxLengthOfUserID方法进行设置。

      在ESFramework内部,组ID(即上面提到的groupID)也采用与UserID相同的规则。

      最后要提醒的是,在能满足项目需求的情况下,尽可能使UserID的最大长度短一点,这样可以使得消息头更加短小,从而避免浪费本不需要的带宽。尤其在高性能、巨大并发的应用中,这点就更关键了。

 

5.消息的最大长度

     Rapid引擎内部默认设置的消息的最大长度为1M(1024*1024),并且这个长度还包含了上述消息头的长度。如果您的应用需要发的单个信息的长度超过了1M,就会被ESFramework认为是恶意的消息,ESFramework会丢弃该消息并关闭对应的连接。

      我们建议:在能同样满足项目的需求下,应该尽可能地使传送的消息小,这样不仅可以节省带宽,而且还有助于提升并发的性能。如果应用中确实需要信息的长度超过1M,那么可以通过Rapid引擎暴露的内部核心引擎接口来设置所允许的最大消息长度:

(1)服务端:RapidServerEngine暴露的TcpServerEngine内核引擎,可以设置其MaxMessageSize属性的值。

(2)客户端:RapidPassiveEngine暴露的TcpPassiveEngine内核引擎,也可以设置其MaxMessageSize属性的值。

 

 

ESFramework 4.0 概述

 

时间: 2024-10-08 10:31:41

ESFramework 4.0 快速上手(06) -- Rapid引擎(续)的相关文章

ESFramework 4.0 快速上手(01) -- Rapid引擎

(在阅读该文之前,请先阅读 ESFramework 4.0 概述 ,会对本文的理解更有帮助.) ESFramework/ESPlatform 4.0 的终极目标是为百万级的用户同时在线提供支持,因为强大,所以使用也较为复杂,配置也较多.但是如果我们的应用只是一个中小型的通信应用(同时在线5000人以下),直接使用ESPlatform就有点显得杀鸡用牛刀了.ESPlus.Rapid提供了一种快速的方式,来解决类似中小型的通信应用,以最简洁的方式来使用ESFramework. 使用ESPlus.Ra

重登陆模式 --ESFramework 4.0 快速上手(07)

在ESFramework框架中基于TCP的服务端引擎(当然也包括Rapid引擎)都采用了这样一条规则:默认情况下,客户端与服务器成功建立TCP连接以后,服务端会从客户端发过来的第一条消息中取出消息头的UserID属性的值,并将其与对应的TCP连接绑定起来.这样,服务端就知道每一个TCP连接所对应的用户UserID,而当我们要求服务端向某个客户端发送消息时,服务端就知道通过哪个TCP连接进行发送了.TCP连接与UserID是一一对应的,一个TCP连接只能对应一个UserID,同样的,一个UserI

聊天系统Demo,增加Silverlight客户端(附源码)-- ESFramework 4.0 快速上手(09)

      在ESFramework 4.0 快速上手 -- 入门Demo,一个简单的IM系统(附源码)一文中,我们介绍了使用ESFramework的Rapid引擎开发的winform聊天程序,本文我们将在之前demo的基础上添加使用ESFramework.SL开发的Silverlight客户端.这样一来,不仅Silverlight客户端之间可以相互通信,Silverlight客户端还可以跟winform客户端进行通信.如果不了解在Silverlight中如何使用ESFramework,可以先看

使用紧凑的序列化器,数倍提升性能 —— ESFramework 4.0 快速上手(11)

在分布式通信系统中,网络传递的是二进制流,而内存中是我们基于对象模型构建的各种各样的对象,当我们需要将一个对象通过网络传递给另一个节点时,首先需要将其序列化为字节流,然后通过网络发送给目标节点,目标节点接收后,再反序列化为对象实例.在ESFramework体系中,也是遵循同样的规则.       ESFramework称这些需要经过网络传递的对象称之为协议类(Contract),协议类通常只是一个简单的数据结构封装,用于保存状态的一个哑类(不包含任何方法,从object继承的除外),有点类似于与

客户端登录验证 -- ESFramework 4.0 快速上手(15)

      在之前版本的Rapid引擎中,是没有提供客户端登陆验证的机制的,如果要验证用户的帐号密码信息,我们只有自己手动通过自定义信息来实现.在2011.04.25发布的新版本中,客户端Rapid引擎,则内置了在初始化时验证用户的帐号密码的功能,这使得登录验证变得更加简单.   一. ESPlus.Application.Basic 空间的支持       为了实现验证用户账号密码的功能,ESPlus.Application.Basic 命名空间增加了几个基础设施. (1)ESPlus.App

离线消息如何实现?-- ESFramework 4.0 快速上手(02)

在ESFramework 4.0 快速上手一文中,主要介绍了如何使用ESPlus.Rapid命名空间中的引擎来快速地构建基于TCP的网络通信系统,即使是使用ESPlus.Rapid来进行ESFramework快速开发,也还有很多可以介绍的内容,于是,我想再多写几篇文章来说明现实通信系统中的一些常见需求如何使用ESFramework快速实现.本文是为第一篇,介绍离线消息的原理和实现.   一.如何截获离线消息 阅读了ESFramework 4.0 快速上手朋友都知道,一个在线用户给另一个用户发送文

判定生死的心跳机制 --ESFramework 4.0 快速上手(07)

      在Internet上采用TCP进行通信的系统,都会遇到一个令人头疼的问题,就是"掉线".而"TCP掉线"这个问题远比我们通常所能想象的要复杂的多 -- 网络拓扑纷繁复杂.而从始节点A到终节点B之间可能要经过N多的交换机.路由器.防火墙等等硬件设备,每个硬件设备的相关设定也不统一,再加上网络中可能出现的拥塞.延迟等,使得我们在编程时,处理掉线也非常棘手.   一.从程序的角度看待TCP掉线       TCP掉线的原因可能多种多样.不一而足,比如,客人的电

在Silverlight中使用ESFramework-- ESFramework 4.0 快速上手(05)

Silverlight已经到4.0版本了,已经相当成熟了,在Silverlight中使用socket与服务器进行通信也是常见的需求,所以,作为.NET平台的通信框架,ESFramework支持Silverlight开发是必须的.       ESFramework.SL 即是ESFramework提供的Silverlight开发组件,其完整实现了基于流的TCP客户端网络引擎,并与其非Silverlight的接口完全一致(即是ESFramework 4.0 快速上手文中提到的IRapidPassi

监控自定义信息 —— ESFramework 4.0 快速上手(10)

      在ESFramework 4.0 进阶(02)-- 核心:消息处理的骨架流程一文中,我们介绍了通过挂接IMessageSpy到骨架流程,我们就可以监控到所有收发的消息.由于Rapid引擎已经为我们组装好了默认的骨架流程,如果使用Rapid引擎,我们就无法插入自定义的IMessageSpy.不过没关系,使用Rapid引擎的我们同样可以在服务端监控到客户端发出的所有自定义信息.   一.深入ICustomizeInfoOutter接口 我们已经非常熟悉ICustomizeInfoOutt