重登陆模式 --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;
重登陆模式 --ESFramework 4.0 快速上手(07)的更多相关文章
- 聊天系统Demo,增加Silverlight客户端(附源码)-- ESFramework 4.0 快速上手(09)
在ESFramework 4.0 快速上手 -- 入门Demo,一个简单的IM系统(附源码)一文中,我们介绍了使用ESFramework的Rapid引擎开发的winform聊天程序,本文我们将在之前d ...
- ESFramework 4.0 快速上手(01) -- Rapid引擎
(在阅读该文之前,请先阅读 ESFramework 4.0 概述 ,会对本文的理解更有帮助.) ESFramework/ESPlatform 4.0 的终极目标是为百万级的用户同时在线提供支持,因为强 ...
- 如何使用自定义消息?--ESFramework 4.0 快速上手(04)
在ESFramework 4.0 快速上手一文中,我们讲述了如何使用Rapid引擎可以快速地上手ESFramework开发,文中介绍了使用ESPlus.Application.CustomizeInf ...
- 聊天系统Demo,增加文件传送功能(附源码)-- ESFramework 4.0 快速上手(14)
本文我们将介绍在ESFramework 4.0 快速上手(08) -- 入门Demo,一个简单的IM系统(附源码)的基础上,增加文件传送的功能.如果不了解如何使用ESFramework提供的文件传送功 ...
- ESFramework 4.0 快速上手(06) -- Rapid引擎(续)
<ESFramework 4.0 快速上手>系列介绍的都是如何使用Rapid引擎(快速引擎) -- RapidServerEngine 和 RapidPassiveEngine.其实,大家 ...
- 离线消息如何实现?-- ESFramework 4.0 快速上手(02)
在ESFramework 4.0 快速上手一文中,主要介绍了如何使用ESPlus.Rapid命名空间中的引擎来快速地构建基于TCP的网络通信系统,即使是使用ESPlus.Rapid来进行ESFrame ...
- 客户端登录验证 -- ESFramework 4.0 快速上手(15)
在之前版本的Rapid引擎中,是没有提供客户端登陆验证的机制的,如果要验证用户的帐号密码信息,我们只有自己手动通过自定义信息来实现.在2011.04.25发布的新版本中,客户端Rapid引擎,则内置了 ...
- 一个简单的IM系统(Demo附源码)-- ESFramework 4.0 快速上手(08)
前面的文章已经介绍完了基于ESFramework/ESPlus进行二次开发的所有要点,现在,我们可以开始小试牛刀了. 本文将介绍使用ESFramework的Rapid引擎开发的两个最简单的Demo,E ...
- 文件传送,如此简单--ESFramework 4.0 快速上手(13)
在所有的通信系统中,文件传送是最常见也是最重要的功能之一,ESFramework对文件传送的强大支持也是其亮点之一,使用ESFramework可以非常轻松地实现与文件传送相关的所有需求.ESPlus. ...
随机推荐
- Tarjan算法详解
Tarjan算法详解 今天偶然发现了这个算法,看了好久,终于明白了一些表层的知识....在这里和大家分享一下... Tarjan算法是一个求解极大强联通子图的算法,相信这些东西大家都在网络上百度过了, ...
- 采用Jenkins搭建持续集成环境
Jenkins介绍 Jenkins是一个CI工具.它可以根据设定持续定期编译,运行相应代码:运行UT或集成测试:将运行结果发送至邮件,或展示成报告... 这样做的最终目的是: 让项目保持健康的状态.如 ...
- 常用的html标签大全
html标签大全 一.文字 1.标题文字 <h#>..........</h#> #=1~6:h1为最大字,h6为最小字 2.字体变化 <font>........ ...
- SQL语句 不足位数补0
select RIGHT('0000'+CAST( '123' AS nvarchar(50)),4) DWBH 公式 RIGHT('位数'+CAST(要判断的字段 AS nvarchar(50)) ...
- 第一百二十一节,JavaScript事件绑定及深入
JavaScript事件绑定及深入 学习要点: 1.传统事件绑定的问题 2.W3C事件处理函数 3.IE事件处理函数 4.事件对象的其他补充 事件绑定分为两种:一种是传统事件绑定(内联模型,脚本模型) ...
- Junit4单元测试之高级用法
Junit单元测试框架是Java程序开发必备的测试利器,现在最常用的就是Junit4了,在Junit4中所有的测试用例都使用了注解的形式,这比Junit3更加灵活与方便.之前在公司的关于单元测试的培训 ...
- [Q]无法卸载怎么办
正确卸载CAD批量打图精灵的方法是进入操作系统,“控制面版”,然后运行“添加和删除程序”,找到CAD批量打图精灵,选“更改/删除”,按照提示操作,即可进行卸载. 若使用强制卸载工具(如360等)卸载可 ...
- centos 设置删除提示
centos 设置删除.覆盖提示 相信好多用linux的同学都用过cp这个命令来覆盖文件,但是新建的普通用户不会有任何提示,这时候心里就咯噔一下,赶紧看看新文件的是不是传上去了.如果加上提示,是不是就 ...
- group by 和count 联合使用问题
工作中要根据用户发布的产品数量来排序做分页,使用group by uid 用count(uid) 来统计的数量和想要的数量不正确. count统计的数量是被group by 分组以后每一组中数据的数量 ...
- 记录下actionbar的翻译
http://blog.csdn.net/xyz_lmn/article/details/8132420 嗯,actionbarSherLock不错,viewpagerIndicator也不错.