ESFramework介绍之(17)―― 支持漫游用户和跨区域功能请求

简介: 对于漫游用户的支持和跨区域功能请求的支持是ESFramework最基本的目的之一(回顾),在详细讲述解决方案之前,先了解一下关于这个问题的上下文。    在我们前面讲述的4层C/S架构中,每个AS负责一块区域。

    对于漫游用户的支持和跨区域功能请求的支持是ESFramework最基本的目的之一(回顾),在详细讲述解决方案之前,先了解一下关于这个问题的上下文。
    在我们前面讲述的4层C/S架构中,每个AS负责一块区域。比如上海AS负责处理所有目标城市为上海的功能请求和管理所有在上海AS上注册的用户(比如PDA用户或手机用户)。如果一个本是在上海注册的用户出差来到了武汉,最方便的,他会连上武汉的AS,这样对于武汉AS来说,这个用户就是漫游用户了。
    如果上海的用户登陆上了上海的AS,但是他需要请求目标城市为武汉的服务,这个请求就是跨区域的请求,上海AS处理不了,需要转发给武汉AS处理。
    还有一种情况,就是即时消息,比如登录到上海AS的用户需要和登录到武汉AS的用户进行即时通讯,这些即时消息都需要在不同的AS之间进行中转,然后最终转发给目标用户。
    ESFramework对上面的各种情况都给予了充分完善的支持。首先,我们解决第一个问题――支持漫游用户。
    单纯的支持漫游用户,非常容易做到。重要的是我们需要为即时通讯信息作准备。当一个用户想查询他的某个“好友”是否在线时,如果目标好友没有漫游,那么,只需要询问其注册的的AS就可以知道答案,但是如果其漫游到异地AS了了?难道我们需要去轮询成千上万个AS中的每一个吗?这样的效率是无法忍受的。ESFramework是通过引入IRamblesManager接口解决这个问题。

1     public   interface  IRamblesManager
2      {
3           int      GetResideCityCode( string  userID) ;  // 用户注册(手机号码)所属地
4           int      GetUserCurrCityCode( string  userID) ;  // 用户当前所在地
5           void     RemoveRambles( string  userID) ;
6           void     RegisterRambles( string  userID , int  cityCode) ;
7      }

    IRamblesManager接口用于管理所有的漫游用户,它记录了每个漫游用户的当前所在区域。这个接口在每个AS发现漫游用户时调用。比如,当某个用户登录到上海AS,上海AS发现这个用户不是在上海注册的,于是,它调用IRamblesManager接口把该用户添加到漫游记录表中。这个漫游记录表可能位于某个公共的数据库中、也可能位于某台7*24小时运行的服务器的内存中。IRamblesManager接抽象了这些具体的物理实现。每个AS通过与IRamblesManager交互就可以知道某个用户是否漫游了、以及漫游到了何地等信息。

    解决了漫游用户后,我们现在转向第二个问题,如何支持跨区域的功能请求?
    前面的系列文章已经讲到,所有的功能请求都是通过消息处理器来处理的,对于跨区域的功能请求,ESFramework提供了跨区域的功能处理器来处理。其仍然实现了IDataDealer接口。下面列出跨区域功能处理器的DealRequestMessage方法的实现代码:

 1         public  NetMessage DealRequestMessage(NetMessage reqMsg)
 2          {
 3               try
 4              {
 5                   // 从IRAS获取目标AS的地址
 6                   string  serverIp  =   this .irasRemotingAccesser.GetAppServerIp(reqMsg.Header.TypeKey) ;    
 7                   if (serverIp  ==   null )
 8                  {
 9                       return   this .contractHelper.GetResponseByServiceResultType(reqMsg ,ServiceResultType.ServiceStopped) ;
10                  }
11                  
12                   // 获取目标AS发布的远程服务句柄
13                  IAsRemotingService_4As asRemotingAccesser  =  (IAsRemotingService_4As)NetHelper.GetRemotingHanler( this .myConfiguration.RemotingChannelTypeStr ,serverIp , this .myConfiguration.AsRemotingPort , this .myConfiguration.AsRemoting4AsServiceName , typeof (IAsRemotingService_4As)) ;
14                   if (asRemotingAccesser  ==   null )
15                  {
16                       return   this .contractHelper.GetResponseByServiceResultType(reqMsg ,ServiceResultType.ServiceStopped) ;
17                  }
18 
19                   // Hook
20                  NetMessage hookedMsg  =   this .netMessageHook.CaptureBeforeSendMsg(reqMsg) ;
21 
22                   // 目标AS处理跨区域请求
23                   return  asRemotingAccesser.DealRequestMessage(hookedMsg) ;
24              }
25               catch (Exception ee)
26              {
27                  ee  =  ee ;
28                   this .esbLogger.Log(ee.Message , " ESFramework.Architecture.LBS.FourTier.ForeignDealer "  ,ErrorLevel.Standard) ;
29                   return   this .contractHelper.GetResponseByServiceResultType(reqMsg ,ServiceResultType.ServiceStopped) ;
30              }
31          }

    上面的代码和注释已经非常清楚了说明了跨区域请求是如何被处理的,这里就不赘言了。只是需要注意,所有的功能请求都是通过远程服务接口提供服务的。
    
    最后,说一说上面描述上下文时提到的第三种情况,AS是如何处理即时通讯消息的?即时通讯消息在ESFramework种称为P2PMessage,对于P2PMessage当然也有对应的消息处理器P2PMessageDealer,它负责将P2PMessage转发给指定的目标用户。P2PMessageDealer的工作方式如下,如果发现目标用户就在本地AS上,则直接转发。如果目标用户是异地用户或者已经漫游到异地,则将消息转发到目标AS上。P2PMessageDealer的实现借助了IToClientSender接口,IToClientSender接口向应用屏蔽了底层的消息转发过程,其定义如下:

    ///   <summary>
    
///  ToClientSender 将数据(一个完整的请求--header+body)转发给目标用户。隐藏了目标用户的位置
    
///  目标用户可能连接在其它服务器节点上    
    
///   </summary>
     public   interface  IToClientSender
    {
        
int  HookAndSendMessage( string  userID ,NetMessage msg) ;     // 返回DataSendResult的常量
    }

    ESFramework中的IToClientSender实现是ToClientSender,它可以包含一组具体的Sender,每次发送消息时,ToClientSender会按照指定的顺序调用每个Sender,知道有一个发送成功为止。ToClientSender实现如下:

    public   class  ToClientSender :IToClientSender
    {
        
private  IList senderList  =   new  ArrayList() ;        

        
public  ToClientSender()
        {            
        }

        
#region  property
        
public  IList SenderList
        {
            
set
            {
                
this .senderList  =  value ;
            }
        }
        
#endregion

        
#region  IToClientSender 成员
        
public   int  HookAndSendMessage( string  userID ,NetMessage msg)
        {
            
int  theResult  =  DataSendResult.UserIsOffLine ;            

            
foreach (IToClientSender sender  in   this .senderList)
            {
                
int  res  =  sender.HookAndSendMessage(userID ,msg) ;
                
if (res  ==  DataSendResult.Succeed)
                {
                    
return  DataSendResult.Succeed ;
                }    
            
                
if (res  !=  DataSendResult.UserIsOffLine)
                {
                    theResult 
=  res ;
                }
            }

            
return  DataSendResult.UserIsOffLine ;
        }

        
#endregion

    }

    当我们在配置应用时,ToClientSender的SenderList通常只包含两个Sender――ToLocalClientSender和ToForeignClientSender。ToLocalClientSender在AS内部传递要转发的消息,而ToForeignClientSender跨AS传递要转发的消息。ToLocalClientSender的实现非常简单:

 1         public   int  HookAndSendMessage( string  userID ,NetMessage msg)
 2          {
 3               bool  onLine  =   this .tcpUserManager.IsUserOnLine(userID) ;
 4               if (onLine)
 5              {
 6                   int  connectID  =   this .tcpUserManager.GetUserConnectID(userID) ;
 7                   this .hookSender.HookAndSendNetMessage(connectID ,msg) ;
 8                   return  DataSendResult.Succeed ;
 9              }    
10          
11               return  DataSendResult.UserIsOffLine ;
12          }

    tcpUserManager是用户管理者组件,它管理了所有的在线用户。关于它的详细描述会在后文中给出。
    ToForeignClientSender通过借助IRamblesManager和AS发布的远程服务接口也实现了跨区域消息的转发。

 1         public   int  HookAndSendMessage( string  userID, NetMessage msg)
 2          {
 3               try
 4              {
 5                   int  userCurCityCode  =   this .ramblesManager.GetUserCurrCityCode(userID) ;
 6                   if ( this .myConfiguration.CityCode  ==  userCurCityCode)
 7                  {
 8                       return  DataSendResult.UserIsOffLine ;
 9                  }
10 
11                   string  destAppServerIp  =   this .irasRemotingAccesser.GetAppServerIp(userCurCityCode) ;
12                   if (destAppServerIp  ==   null )
13                  {
14                       return  DataSendResult.UserIsOffLine ;
15                  }
16 
17                  IAsRemotingService_4As asRemotingAccesser  =  (IAsRemotingService_4As)NetHelper.GetRemotingHanler( this .myConfiguration.RemotingChannelTypeStr ,destAppServerIp , this .myConfiguration.AsRemotingPort , this .myConfiguration.AsRemoting4AsServiceName , typeof (IAsRemotingService_4As)) ;
18                   if (asRemotingAccesser  ==   null )
19                  {
20                       return  DataSendResult.UserIsOffLine ;
21                  }
22 
23                  NetMessage hookedMsg  =   this .netMessageHook.CaptureBeforeSendMsg(msg) ;
24                   return  asRemotingAccesser.HookAndSendMessage(userID ,msg) ;    
25              }
26               catch (Exception ee)
27              {
28                  ee  =  ee ;
29                   this .esbLogger.Log(ee.Message , " ESFramework.Architecture.LBS.FourTier.ToForeignClientSender "  ,ErrorLevel.Standard) ;
30                   return  DataSendResult.FailByOtherCause ;
31              }
32          }
33 

    关于“支持漫游用户和跨区域功能请求”,本文只是对主要的部分作了讲述,还有很多小的细节无法在这里全面展开。如果只是要了解并使用ESFramework框架来帮你搭建应用,了解这些就足够了:)感谢关注!

上一篇文章:ESFramework介绍之(16)―― Tcp数据自动发送器ITcpAutoSender

转到  :ESFramework 可复用的通信框架(序) 

 

目录
相关文章
|
11月前
|
存储 前端开发 安全
跨页面通信的方式有哪些?
跨页面通信的方式有哪些?
176 0
|
3月前
|
编解码 网络协议 前端开发
如何实现Android平台GB28181设备接入模块按需打开摄像头并回传数据
后台采集摄像头,如果想再进一步扩展,可以把android平台gb28181的camera2 demo,都移植过来,实现功能更强大的国标设备侧,这里主要是展示,收到国标平台侧的回传请求后,才打开摄像头,才开始编码打包,最大限度的减少资源的占用
|
6月前
|
监控 网络协议 数据安全/隐私保护
运用自定义协议设计与实现“跨网络计算器”
运用自定义协议设计与实现“跨网络计算器”
67 3
|
6月前
|
存储 移动开发 API
本地跨页面通讯
本地跨页面通讯包括Web Storage、Cookies、Broadcast Channel API、SharedWorker和postMessage API等方法。Web Storage和Cookies用于存储数据共享,Broadcast Channel API提供消息通道,SharedWorker支持多页面共享后台线程,postMessage用于不同窗口或页面间的消息传递。根据项目需求选择合适的技术,可实现高效通信。
|
6月前
|
存储 前端开发 安全
无限连接:前端跨页面通信的实现与应用
在前端开发中,有时我们需要在不同的页面之间进行数据传递和交互。这种场景下,前端跨页面通信就显得尤为重要。前端跨页面通信是指在不同的页面之间传递数据、发送消息以及实现页面间的交互操作。本文将详细介绍前端跨页面通信的属性、应用场景以及实现方法,并提供一些代码示例和引用资料,帮助读者深入了解并应用这一重要的技术。
|
6月前
|
存储 缓存 JavaScript
跨标签页通信的8种方式(上)
跨标签页通信是指在浏览器中的不同标签页之间进行数据传递和通信的过程。在传统的Web开发中,每个标签页都是相互独立的,无法直接共享数据。然而,有时候我们需要在不同的标签页之间进行数据共享或者实现一些协同操作,这就需要使用跨标签页通信来实现。
171 0
|
6月前
|
存储 JavaScript 前端开发
跨标签页通信的8种方式(下)
跨标签页通信是指在浏览器中的不同标签页之间进行数据传递和通信的过程。在传统的Web开发中,每个标签页都是相互独立的,无法直接共享数据。然而,有时候我们需要在不同的标签页之间进行数据共享或者实现一些协同操作,这就需要使用跨标签页通信来实现。
135 0
|
6月前
|
存储 Web App开发 移动开发
跨页面通信有多少种技术方式可以实现?
跨页面通信有多少种技术方式可以实现?
154 0
|
12月前
|
Web App开发 视频直播
浏览器跨标签页通信、双向数据传输、实时通信有什么区别?
浏览器跨标签页通信、双向数据传输、实时通信有什么区别?
76 0
|
编解码 监控 网络协议
Android平台GB28181设备接入侧如何实现按需打开视音频采集传输
Android平台GB28181设备接入侧如何实现按需打开视音频采集传输
156 2