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

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

一.两种重登陆模式

在现实中,经常出现这样的情况:比如我们用的QQ,当我们用一个账号在A地登陆了,还未下线,而我又用此账号在B地登陆,会发生什么情况?QQ采用的是用新连接取代旧连接的策略,即通知A地的客户端其已经被挤掉线了(如提示“同名的用户已在其它地方登陆”),而对于后续的通信,服务器都将与B地的客户端进行。

  QQ采用的这种模式在ESFramework中称为ReplaceOld模式。但是,有的应用可能需要保留A地的连接而忽略新来的B地的连接,对于这种情况,我们可以采用另外一种模式:IgnoreNew。ESFramework通过RelogonMode枚举来定义这两种模式:

/// <summary>
    /// 重登陆模式。当从另外一个新连接上收到一个同名ID用户的消息时,用户管理器对旧的连接的处理模式。
    /// </summary>
    public enum RelogonMode
    {
        /// <summary>
        /// 忽略新的连接。
        /// </summary>
        IgnoreNew = 0,

/// <summary>
        /// 使用新的连接取代旧的连接。
        /// </summary>
        ReplaceOld
    }

  我们可以设置用户管理器IUserManager的RelogonMode属性来控制ESFramework采用哪种重登陆模式。

二.ESFramework对两种重登陆模式的反应

1.IgnoreNew模式

如果我们采用的是IgnoreNew模式, 当服务端从另外一个新的连接上收到同名用户发来的消息时,ESFramework会触发IUserManager的NewConnectionIgnored事件来通知服务端应用程序:

event CbGeneric<string ,IUserAddress> NewConnectionIgnored;

  事件的第一个参数string是同名用户的ID,第二个参数是新连接的客户端地址。

  服务端必须预定并处理该事件,如何处理了?通常,有两件事是必须要做的:

(1)通知新连接对应的客户端,已经有同名的用户在线了,新的连接将被关闭。

(2)关闭新的连接。

2.ReplaceOld模式

如果我们采用的是ReplaceOld模式, 当服务端从另外一个新的连接上收到同名用户发来的消息时,ESFramework会触发IUserManager的SomeOneBeingPushedOut事件来通知服务端应用程序:

event CbGeneric<UserData> SomeOneBeingPushedOut;

  即同名的老连接对应的客户端被挤掉了,事件的参数包含了旧连接对应的相关信息。

  相应的,服务端也必须预定并处理该事件,并且也是有两件事是必须要做的:

(1)通知旧连接对应的客户端,有同名的用户连接上来,旧的连接将被关闭。

(2)关闭旧的连接。

三.ESPlus让重登陆模式的应用更easy

  ESPlus下的ESPlus.Application.Basic命名空间把上面所说的采用IgnoreNew模式或ReplaceOld模式时,服务端必须做的事情都处理了。比如,通知(新/旧)客户端,关闭(新/旧)TCP连接。

  ESPlus.Application.Basic.Server.BasicMessageProcesser类预定了IUserManager的NewConnectionIgnored和SomeOneBeingPushedOut事件,并在事件处理函数中通知了客户端,且关闭了需要关闭的连接。

  那么客户端应用程序如何知道服务端发来的相关通知了?

  当相关通知被客户端引擎接收到时,ESPlus会回调ESPlus.Application.Basic.Passive.IBasicBusinessHandler接口的OnBeingPushedOut方法或OnHaveLogonNotify方法:

/// <summary>
        /// OnBeingPushedOut 被同名用户挤掉线。此时,客户端引擎已被Dispose。
        /// 发生于RelogonMode.ReplaceOld。
        /// </summary>
        void OnBeingPushedOut();

/// <summary>
        /// OnHaveLogonNotify 当同名的用户已经登录,而且当前连接被忽略(已被服务端关闭)时调用此方法。此时,客户端引擎已被Dispose。
        /// 发生于RelogonMode.IgnoreNew。
        /// </summary>        
        void OnHaveLogonNotify();

  所以,客户端程序只要实现IBasicBusinessHandler接口的这两个方法,就能接收到自己被挤掉线或者同名用户已经登陆的通知了。

四.Rapid引擎与重登陆模式

  支持ESFramework快速开发的Rapid引擎使用刚介绍的ESPlus.Application.Basic命名空间,其内部已经将与重登陆处理相关的组件都已经自动装配好了,所以,我们客户端只要实现上面说的IBasicBusinessHandler接口的两个方法来接收服务端的通知就OK了。

  Rapid引擎默认采用的是ReplaceOld模式,但是可以通过类似下面的语句将IUserManager的重登陆模式设置为IgnoreNew模式。

((IUserManager)rapidServerEngine.UserManager).RelogonMode = RelogonMode.ReplaceOld;

时间: 2024-07-30 22:29:29

重登陆模式 --ESFramework 4.0 快速上手(07)的相关文章

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

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

如何使用自定义消息?--ESFramework 4.0 快速上手(04)

在ESFramework 4.0 快速上手一文中,我们讲述了如何使用Rapid引擎可以快速地上手ESFramework开发,文中介绍了使用ESPlus.Application.CustomizeInfo命名空间下的类可以发送和处理自定义消息,本文我们就通过一个简单的例子来深入讲解如何使用自定义消息. 例子的场景很简单:假设客户端登陆到服务器之后,要求请求加入某个组,服务端收到该请求后,处理该请求,并给客户端相应的回复 -- 是否加入成功,客户端收到回复后,即可作出相应的处理. 一.定义消息类型和

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

<ESFramework 4.0 快速上手>系列介绍的都是如何使用Rapid引擎(快速引擎) -- RapidServerEngine 和 RapidPassiveEngine.其实,大家可以将这两个引擎看作是两个壳,内部包装的才是真正的ESFramework的网络引擎, ESFramework支持很多种网络引擎(客户端/服务端.二进制协议/文本协议.TCP/UDP),而RapidServerEngine和RapidPassiveEngine采用的是基于TCP和二进制协议的服务端引擎和客户端引

离线消息如何实现?-- 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掉线的原因可能多种多样.不一而足,比如,客人的电脑突然断电.OS崩溃.路由器

AutoMapper 9.0快速上手,从老版本迁移到9.0+AutoMapper9.0和Autofac的完美结合

.NET模型映射器AutoMapper 9.0发布了,官方宣称不再支持静态方法调用了,老版本的部分API将在升级到9.0后,直接升级包到9.0会编译报错,所以写篇文章记录下AutoMapper新版本的学习过程吧,如果还不知道AutoMapper是什么的,建议先看这篇文章:https://masuit.com/156,或者参考官方文档:https://automapper.readthedocs.io/en/latest/Getting-started.html AutoMapper9.0快速上手

核心梳理——消息处理的骨架流程——ESFramework 4.0 进阶(02)

在ESFramework 4.0 概述一文中,我们提到ESFramework.dll作为通信框架的核心,定义了消息处理的骨架流程,本文我们来详细剖析这个流程以及该骨架中所涉及的各个组件.ESFramework的骨架流程如下图所示: 一.所有的网络引擎都使用同一消息处理骨架流程 ESFramework支持TCP/UDP.二进制协议/文本协议.服务端/客户端组合而成的2x2x2=8种引擎,无论是哪一种引擎,都实现了INetEngine接口,也都使用上图所示的消息处理骨架流程来处理所接收到的所有消息.

EntityFramework 5.0 CodeFirst 教程01-搭建环境和快速上手

----------------------------目录------------------------------ EntityFramework 5.0 CodeFirst 教程01-搭建环境和快速上手 ----------------------------目录------------------------------ 网上关于EntityFramework 5.0的教程很多,但是大多数都是代码整理不清晰,有些甚至是拷贝,代码丢失等问题,本人最近也有一个项目是用到EntityFram

MongoDB快速上手

1.  MongoDB简介 MongoDB是一个跨平台的基于Key_Value键值对形式保存数据的NoSQL文档类型数据库. NoSQL(not only sql)数据库,泛指非关系型数据库. 1.1 NoSQL数据库的特点 l  不需要预定义模式 不需要事先定义数据模式,预定义表结构.数据中的每条记录都可能有不同的属性和格式.当插入数据时,并不需要预先定义它们的模式. l  无共享架构 相对于将所有数据存储的存储区域网络中的全共享架构.NoSQL往往将数据划分后存储在各个本地服务器上.因为从本