ESFramework 开发手册(06) -- Rapid通信引擎

      ESPlus.Rapid命名空间提供了我们可以直接使用的客户端Rapid引擎和服务端Rapid引擎。Rapid引擎将ESFramework和ESPlus提供的各种组件装配成一个整体,将结构的复杂性隐藏在引擎的内部,而提供给我们一个简单易用的接口。在引擎对象初始化成功之后,我们就可以使用引擎对象暴露出的四大武器了。Rapid引擎底层使用的核心是ESFramework的StreamTcpEngine,其采用TCP协议、并使用了紧凑的二进制消息格式。(说明一下,即使不了解ESFramework更底层的引擎,像StreamTcpEngine,也不会影响Rapid引擎的高效使用。)

 

1.客户端Rapid引擎

      ESPlus.Rapid. IRapidPassiveEngine和ESPlus.Rapid.RapidPassiveEngine分别是客户端Rapid引擎的接口和实现类。观察IRapidPassiveEngine接口的定义,我们就可以了解客户端Rapid引擎的使用方法了。

    public interface IRapidPassiveEngine        
    {
        /// <summary>
        /// 当断线重连成功时,会自动登录服务器验证用户账号密码,并触发此事件。如果验证失败,则与服务器的连接将会断开,且后续不会再自动重连。事件参数表明了登录验证的结果。
        /// </summary>
        event CbGeneric<LogonResponse> RelogonCompleted;

        /// <summary>
        /// 系统标志。引擎在初始化时会提交给服务器验证客户端是否是正确的系统。
        /// </summary>
        string SystemToken { get; set; }

        /// <summary>
        /// 当前登录的用户UserID。
        /// </summary>
        string CurrentUserID { get; }

        /// <summary>
        /// 每隔多长时间(秒)发送一次心跳消息。如果小于等于0,表示不发送定时心跳。默认值为5秒。
        /// </summary>
        int HeartBeatSpanInSecs { get; set; }

        /// <summary>
        /// 当通过ICustomizeOutter进行同步调用时,等待回复的最长时间。如果小于等于0,表示一直阻塞调用线程直到等到回复为止。默认值为30秒。
        /// </summary>
        int WaitResponseTimeoutInSecs { get; set; }

        /// <summary>
        /// Sock5代理服务器信息。如果不需要代理,则设置为null。
        /// </summary>
        Sock5ProxyInfo Sock5ProxyInfo { get; set; }

        /// <summary>
        /// 对于基于UDP的P2P通道,是否启用可靠的UDP。默认值为true。
        /// </summary>
        bool ReliableUdpEnabled { get; set; }

        /// <summary>
        /// 这是RapidPassiveEngine内部使用的真正的客户端通信引擎的接口。
        /// </summary>
        ITcpPassiveEngine TcpPassiveEngine { get; }

        /// <summary>
        /// 该接口用于向服务器发送基本的请求,如获取自己的IP、获取所有在线用户列表等等。
        /// </summary>
        IBasicOutter BasicOutter { get; }

        /// <summary>
        /// 该接口用于向服务器或其它在线用户发送自定义信息。
        /// </summary>
        ICustomizeOutter CustomizeOutter { get; }

        /// <summary>
        /// 该接口用于向服务器或其它在线用户发送文件。
        /// </summary>
        IFileOutter FileOutter { get; }

        /// <summary>
        /// 该接口用于控制和管理所有的P2P通道。
        /// </summary>
        IP2PController P2PController { get; }     

        /// <summary>
        /// 完成客户端引擎的初始化,与服务器建立TCP连接,连接成功后立即验证用户密码。如果连接失败,则抛出异常。
        /// </summary>
        /// <param name="userID">当前登录的用户ID,由数字和字母组成,最大长度为10</param>
        /// <param name="logonPassword">用户登陆密码。</param>
        /// <param name="serverIP">服务器的IP地址。</param>
        /// <param name="serverPort">服务器的端口。</param>       
        /// <param name="customizeHandler">自定义处理器,用于处理服务器或其它用户发送过来的消息</param>               
        LogonResponse Initialize(string userID, string logonPassword, string serverIP, int serverPort, ICustomizeHandler customizeHandler);
 

        /// <summary>
        /// 关闭客户端通信引擎。
        /// </summary>
        void Close();
    }

属性

  • 请注意,如果需要通过引擎的setter属性设置某些参数(如HeartBeatSpanInSecs等),必须在调用Initialize方法之前设置才能生效。如果要通过引擎的getter属性使用某些组件(如BasicOutter),必须在引擎初始化成功后,才能正常使用。
  • 当客户端通过代理服务器上Internet时,可以通过Sock5ProxyInfo属性来设置Sock5代理的相关信息。
  • 正如在介绍Basic空间所述,SystemToken属性的值用于作为参数传递到服务端IBasicBusinessHandler接口的VerifyUser方法,以进行登陆验证。
  • WaitResponseTimeoutInSecs属性用于设置同步调用(以及ACK机制的信息发送)时等待回复的超时时间。
  • ReliableUdpEnabled属性用于控制基于UDP的P2P通道是否采用可靠的UDP通信,如果启用,将使得创建成功的所有P2P通道都是可靠的。
  • TcpPassiveEngine、BasicOutter、CustomizeOutter、FileOutter、P2PController等属性,我们已经在前面章节详细描述了,不再赘述。

方法

  • 参数设置好后,就可以调用Initialize方法进行初始化。Initialize方法需要的Handler参数已经在前面详细介绍了,不再赘述。
  • 正如在TCP连接状态小节讲到的 ,当TCP重连成功时,Rapid客户端引擎会自动登录服务器重新验证用户账号和密码,并触发RelogonCompleted事件。开发人员应该依据IRapidPassiveEngine的RelogonCompleted事件来作为重连成功/失败的依据。
  • 当不再需要使用引擎实例时,调用Close方法以释放资源。

 

 

2.服务端Rapid引擎

     ESPlus.Rapid. IRapidServerEngine和ESPlus.Rapid.RapidServerEngine分别是客户端Rapid引擎的接口和实现类。我们来看看IRapidServerEngine接口的定义。

     public interface IRapidServerEngine
     {        

        /// <summary>
        /// 通过哪个IP地址提供服务。如果设为null,则表示绑定本地所有IP。默认值为null。
        /// </summary>
        string IPAddressBinding { get; set; }

        /// <summary>
        /// 心跳超时间隔(秒)。即服务端多久没有收到客户端的心跳消息,就视客户端为超时掉线。默认值为30秒。如果设置小于等于0,则表示不做心跳检查。
        /// </summary>
        int HeartbeatTimeoutInSecs { get; set; }

        /// <summary>
        /// 当通过ICustomizeController进行同步调用客户端时,等待回复的最长时间。如果小于等于0,表示一直阻塞调用线程直到等到回复为止。默认值为30秒。
        /// </summary>
        int WaitResponseTimeoutInSecs { get; set; }

        /// <summary>
        /// 是否自动回复客户端发过来的心跳消息(将心跳消息原封不动地发回客户端)。默认值为true。
        /// </summary>
        bool AutoRespondHeartBeat { get; set; }

        /// <summary>
        /// 当用户上线/掉线时,是否通知其好友。默认值true。
        /// </summary>
        bool FriendNotifyEnabled { get; set; }

        /// <summary>
        /// 当用户上线/掉线时,是否通知其组友(groupmate)。默认值false。
        /// </summary>
        bool GroupNotifyEnabled { get; set; }

        /// <summary>
        /// 通过此接口,可以获取用户的相关信息以及用户上/下线的事件通知。
        /// </summary>
        IUserManager UserManager { get; }

        /// <summary>
        /// 平台用户管理器(用于ESPlatform,通常为ASM的远程引用)。可以获取群集中所有在线用户信息。
        /// </summary>
        IPlatformUserManager PlatformUserManager { get; }

        /// <summary>
        /// 通过此接口,服务端可以发送广播消息和将目标用户从服务器中踢出,并关闭其对应的tcp连接。
        /// </summary>
        IBasicController BasicController { get; set; }

        /// <summary>
        /// 通过此接口,服务端可以主动向在线用户发送/投递自定义信息。
        /// </summary>
        ICustomizeController CustomizeController { get; }

        /// <summary>
        /// 通过此接口,服务端可以主动向在线用户发送文件。
        /// </summary>
        IFileController FileController { get; }

        /// <summary>
        /// 完成服务端引擎的初始化,并启动服务端引擎。
        /// </summary>
        /// <param name="port">用于提供tcp通信服务的端口</param>
        /// <param name="customizeHandler">服务器通过此接口来处理客户端提交给服务端自定义信息。</param>
        void Initialize(int port, ICustomizeHandler customizeHandler);

        /// <summary>
        /// 完成服务端引擎的初始化,并启动服务端引擎。
        /// </summary>
        /// <param name="port">用于提供tcp通信服务的端口</param>
        /// <param name="customizeHandler">服务器通过此接口来处理客户端提交给服务端自定义信息。</param>
        /// <param name="basicHandler">用于验证客户端登陆密码。如果不需要验证,则直接传入null。</param>
        /// <param name="friendManager">服务器通过此接口来获取好友关系。如果系统中不需要支持好友关系,则可传入null。</param>
        /// <param name="groupManager">服务器通过此接口来获取某个分组内的成员列表信息。如果系统中不需要支持组,则可传入null。</param>
        void Initialize(int port, ICustomizeHandler customizeHandler, IBasicHandler basicHandler,  IFriendManager friendManager, IGroupManager groupManager);
 

        /// <summary>
        /// 关闭服务端引擎。
        /// </summary>
        void Close();
    }

属性

  • 请注意,同客户端一样,如果需要通过引擎的setter属性设置某些参数(如FriendNotifyEnabled等),必须在调用Initialize方法之前设置才能生效。如果要通过引擎的getter属性使用某些组件(如UserManager),必须在Initialize方法执行成功后,才能正常使用。
  • FriendNotifyEnabled和GroupNotifyEnabled属性用于控制用户上下线时,是否自动通知其好友和组友 - - 即如果通知的话,将在客户端触发IBasicOutter的FriendConnected、FriendOffline 、GroupmateConnected、GroupmateOffline 事件。
  • PlatformUserManager 用于ESPlatform,通过它可以获取群集中所有在线用户信息。当没有群集存在时,PlatformUserManager等同于UserManager。
  • BasicController、CustomizeController、FileController、UserManager的作用我们前面已经详细介绍了,这里不再赘述。

方法

  • 参数设置好后,就可以调用Initialize方法进行初始化。Initialize方法需要的Handler参数已经在前面详细介绍了,不再赘述。关于IFriendManager和IGroupManager参数分别用于管理好友和组,其详细介绍请参见好友与组
  • 当不再需要使用引擎实例时,调用Close方法以释放资源。

默认主窗体

      我们的所有Demo都是使用的ESPlus提供的默认主窗体ESPlus.Widgets.MainServerForm。 一般,只有在调试和测试阶段,我们才会使用该窗体来实时显示每个在线用户的状态。在正式发布时,则建议不要使用该窗体了。特别是在高性能的应用中,该窗体会实时刷新每个用户的状态数据,其消耗CPU是不可忽视的(可以通过将MainServerForm构造函数的showUserList参数设为false,来关闭用户状态显示)。MainServerForm的构造函数如下所示:

public MainServerForm(IRapidServerEngine rapidServerEngine, bool showUserList)

      当服务端Rapid引擎初始化成功之后,就可以构造MainServerForm并将其显示出来了,其截图如下:

     

      简单提一下,图中显示的设备类型可以是.NET客户端、Silverlight客户端、ios客户端等等。不同平台的客户端引擎可以连接上同一个服务器,并相互通信。

      如果具体的应用需要在主窗体中做更多的事情,则需要自己来实现。后面我们会放出MainServerForm的源码,大家也可以在其基础上添加所需的功能。

      当然,我们也可以在windows服务中使用服务端Rapid引擎,主要在windows服务启动的时候初始化Rapid引擎就可以了,这样就不需要主窗体了,而且,这样节省了UI刷新所消耗的性能。

 

 

3.ESFramework二次开发要点

      当基于ESFramework/ESPlus开发分布式通信应用时,可以遵循下面的步骤:

(1) 系统中的客户端用户之间是否存在好友关系、是否需要相互通信?如果是,则要实现IFriendManager接口;否则,直接使用ESPlus提供的EmptyFriendManager类。

(2) 系统中是否需要将客户端用户进行分组/群、是否需要在组内进行广播消息?如果是,则要实现IGroupManager接口;否则,直接使用ESPlus提供的EmptyGroupManager类。

3) 分析项目需求,定义所有的自定义信息类型和自定义信息协议。

(4) 在客户端和服务端分别实现各自的ICustomizeHandler接口,用于处理自定义信息、完成系统业务功能。

(5) 在服务端实现IBasicHandler接口,用于验证用户账密。如果不需要验证,则直接使用ESPlus提供的EmptyBasicHandler。

(6) 实例化客户端和服务端Rapid引擎,设置相关属性的值,并将上述各实现类的对象传入相应的Initialize方法。

(7) 在客户端,预定并处理引擎的TcpPassiveEngine属性暴露的连接状态变化事件。如果有需要,还可以预定并处理BasicOutter的相关状态通知事件。在服务端,预定并处理Rapid引擎的UserManager属性的用户状态变化事件。

(8) 使用引擎实例通过属性暴露的四大武器,进一步实现系统业务功能。

      到此为止,我们已经将基于ESFramework/ESPlus进行二次开发所需要掌握的所有基础设施都已介绍完毕,大家基本可以上手ESFramework/ESPlus开发了。如果,现在大家再去阅读我们demo的源码,应该就更清楚明白了。

      后续我们将写一些高阶一点的文章,帮助大家更好地理解和使用ESFramework。敬请关注,谢谢。

      阅读 更多ESFramework开发手册系列文章

-----------------------------------------------------------------------------------------------------------------------------------------------

下载免费版本的ESFramework 以及 demo源码

关于ESFramework的任何问题,欢迎联系我们:

电话:027-87638960

Q Q:372841921

 


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值