ESFramework网络通信框架介绍之(5)――消息分派器IMessageDispatcher

  从2004年7月开始,就一直从事N层C/S架构的服务端的开发,时至今日,慢慢的积累了一些开发经验,ESFramework网络通信框架体系便是这些经验的总结。ESFramework网络通信框架这是一套完全可复用的、灵活的、单纯的、支持N层C/S架构的网络通信框架,内置了对Tcp和Udp协议的支持。ESFramework网络通信框架不仅仅提供了一个基础的C/S框架和大量C/S应用中常用的组件,而且在ESFramework网络通信框架框架之上,引入的一个扩展层--ESFramework网络通信框架扩展层,专门用于解决的与具体应用相关的领域问题。

一.ESFramework网络通信框架与消息分派器

 

(本文原作于2006.03.14,第一次修正于2006.06.06,修正后适用于ESFramework V0.3+)

    本来Tcp/udp组件是系统与外界交换消息的唯一进出口,而Tcp组件或Udp组件与我们系统唯一的联系是通过消息分派器IMessageDispatcher,如此一来,就相当于ESFramework规定了消息分派器是我们应用与外界交换消息的进出口。IMessageDispatcher是与协议无关、宿主无关的组件,即,它即可以在使用于TCP协议也可使用于Udp协议,如果使用Remoting的方式通信也可以使用IMessageDispatcher来分派消息;它即可以用在服务端也可以用于客户端,这样的高可复用性使得基于不同底层(如Tcp/Udp、服务端/客户端)构建的上层应用具有高度的统一性,同时使得ESFramework网络通信框架的整个架构更加清晰、学习曲线更平滑。

    IMessageDispatcher保证接收到的每个消息和发送出去的每个消息都能被所有的HookSpy所截获。另外,消息分派器可能需要验证接收到的每个消息格式是否正确、消息是否合法、消息是否符合特定规格等。下面是消息分派器组件的组成:
    
   
    消息分派器IMessageDispatcher定义如下:
   

    public interface IMessageDispatcher
    {
        IEsbLogger           EsbLogger{set ;}        
        INetMessageHook       NetMessageHook{set ;}//可为EsbNetMessageHook
        IGatewayMessageSpy GatewayMessageSpy{set;}
        IInnerMessageSpy   InnerMessageSpy{set;}    

        IContractHelper       ContractHelper{set ;}//必须设置
        INakeDispatcher    NakeDispatcher{set ;} //必须设置

        NetMessage DispatchMessage(NetMessage reqMsg) ;
        
        /// <summary>
        /// 如所有的SingleMessage在发送之前必须经过IMessageDispatcher的Hook链和Spy
        /// </summary>        
        NetMessage BeforeSendMessage(NetMessage msg) ;

        event CbNetMessage MessageReceived ;
    }    

    从IMessageDispatcher的组件结构图和接口的定义可以看出,IMessageDispatcher保证了将接受到的消息按照规定的顺序经过各个Spy、Hook、消息处理器等组件。任何消息不得例外。即使是系统内部生成的消息(如发给客户端的通知),也必须经过IMessageDispatcher的BeforeSendMessage后才可安全的发送出去。
    IMessageDispatcher的实现如下所示:

    public class MessageDispatcher :IMessageDispatcher
    {
        #region property
        #region Logger
        private IEsbLogger esbLogger = new EmptyEsbLogger() ;
        public  IEsbLogger EsbLogger
        {
            set
            {
                if(value != null)
                {
                    this.esbLogger = value ;
                }
            }
        }
        #endregion

        #region NakeDispatcher    
        private INakeDispatcher nakeDispatcher ;
        public  INakeDispatcher NakeDispatcher
        {
            set
            {
                this.nakeDispatcher = value ;
            }
        }
        #endregion                

        #region NetMessageHook
        private INetMessageHook netMessageHook = new EmptyNetMessageHook() ;
        public  INetMessageHook NetMessageHook 
        {
            set
            {
                this.netMessageHook = value ;
            }
        }
        #endregion

        #region InnerMessageSpy        
        private IInnerMessageSpy innerMessageSpy = new EmptyInnerMessageSpy() ;
        public  IInnerMessageSpy InnerMessageSpy
        {
            set
            {
                if(value != null)
                {
                    this.innerMessageSpy = value ;
                }

            }
        }
        #endregion
        
        #region GatewayMessageSpy    
        private IGatewayMessageSpy gatewayMessageSpy = new EmptyGatewayNetMessageSpy() ;
        public  IGatewayMessageSpy GatewayMessageSpy
        {
            set
            {
                if(value != null)
                {
                    this.gatewayMessageSpy = value ;
                }
            }
        }
        #endregion

        #region ContractHelper
        private IContractHelper contractHelper = null ;
        public  IContractHelper ContractHelper
        {
            set
            {
                this.contractHelper = value ;
            }
        }
        #endregion

        public event CbNetMessage MessageReceived;
        #endregion

        #region IMessageDispatcher 成员    

        public NetMessage DispatchMessage(NetMessage reqMsg)
        {
            try
            {
                if(this.MessageReceived != null)
                {
                    this.MessageReceived(reqMsg) ;
                }

                this.gatewayMessageSpy.SpyReceivedMsg(reqMsg) ;

                NetMessage msgHooked = this.netMessageHook.CaptureReceivedMsg(reqMsg) ;

                
                this.innerMessageSpy.SpyReceivedMsg(msgHooked) ;                
                NetMessage resMsg = this.nakeDispatcher.DispatchMessage(msgHooked) ;
                if(reqMsg == null)
                {
                    return null ;
                }
                
                return this.BeforeSendMessage(resMsg) ;
            }
            catch(Exception ee)
            {
                this.esbLogger.Log(ee.GetType().ToString() ,ee.Message ,"ESFramework.Network.MessageDispatcher.DispatchMessage" ,ErrorLevel.High) ;
                return this.contractHelper.GetResponseByServiceResultType(reqMsg ,ServiceResultType.HandleFailure) ;                    
            }
        }

        public NetMessage BeforeSendMessage(NetMessage msg)
        {
            this.innerMessageSpy.SpyToBeSendedMsg(msg) ;
            NetMessage msgHooked = this.netMessageHook.CaptureBeforeSendMsg(msg) ;
            this.gatewayMessageSpy.SpyToBeSendedMsg(msgHooked) ;

            return msgHooked ;            
        }

        #endregion
    }

    我们看到,IMessageDispatcher内部使用了INakeDispatcher组件,INakeDispatcher的职责比较单纯,它针对需要分派的消息调用IDataDealerFactory创建对应的处理器,然后将消息交给处理器处理后,将结果返回。其接口定义如下:

    public interface INakeDispatcher
    {
        NetMessage DispatchMessage(NetMessage msg) ;
    }

    INakeDispatcher的实现也非常简单:

    public class NakeDispatcher :INakeDispatcher
    {
        #region DataDealerFactory
        private IDataDealerFactory dataDealerFactory = null ; 
        public  IDataDealerFactory DataDealerFactory
        {
            set
            {
                this.dataDealerFactory = value ;
            }
        }
        #endregion
        
        #region ContractHelper
        private IContractHelper contractHelper = null ; 
        public  IContractHelper ContractHelper
        {
            set
            {
                this.contractHelper = value ;
            }
        }
        #endregion     

        #region INakeDispatcher 成员

        public NetMessage DispatchMessage(NetMessage msg)
        {
            IDataDealer dealer = this.dataDealerFactory.CreateDealer(msg.Header.ServiceKey ,msg.Header.TypeKey) ;
            if(dealer == null)
            {
                return this.contractHelper.GetResponseByServiceResultType(msg ,ServiceResultType.ServiceIsNotExist) ;
            }

            return dealer.DealRequestMessage(msg) ;
        }

        #endregion
    }

    通常,在客户端使用IMessageDispatcher组件时,我们不需要使用GatewayMessageSpy和InnerMessageSpy,如果是这样,那么我们只要不为MessageDispatcher的GatewayMessageSpy属性和InnerMessageSpy属性注入对象就可以了。

上一篇:ESFramework网络通信框架介绍之(4)――消息拦截器INetMessageHook
转到  :ESFramework 可复用的(序) 

 

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-07-31 04:11:16

ESFramework网络通信框架介绍之(5)――消息分派器IMessageDispatcher的相关文章

ESFramework网络通信框架介绍之(2)――网络通信消息NetMessage

ESFramework网络通信框架与元数据 较之C++而言,.NET是一个更加"动态"的平台,其动态能力建立在反射机制之上,而反射的基础是"元数据".     上文已经提到过,如果一个框架要为我们的应用做更多的事情,那么这个框架必须建立更多的标准,必须对框架自己要处理的消息有更多的了解,所以,每个消息都要是自描述的,也就是说每个消息要包含它自己的"元数据".那么,"元数据"位于消息的何处了?你一定想到了,对,是消息头(Mess

ESFramework网络通信框架介绍之(1)――网络通信消息协议接口IContract

一.ESFramework网络通信框架与字节流        通过网络通信的系统之间(如客户端与服务端的通信)要想正常交互,它们必须有"共同的语言",这种语言就是消息协议.遵守消息协议的消息才能被我们的系统所理解.    我们知道,消息在网路上传输的是字节流,而我们主流的面向对象系统中处理的却是"对象",如何将从网络上接收到的字节流转化为"对象",又如何将"对象"转化为字节流以便通过网络传递给其他系统,这便是IContract

ESFramework网络通信框架介绍之(3)――消息处理器和处理器工厂

一.ESFramework网络通信框架与消息处理器   无论是服务端还是客户端,都需要对接收到的消息进行处理,在ESFramework网络通信框架中,处理消息的组件称为消息处理器,所有的消息处理器都实现了接口IDataDealer:    1     public interface IDataDealer2     {        3         NetMessage  DealRequestMessage(NetMessage reqMsg) ;        4     }    

ESFramework网络通信框架 4.0 性能测试

  本实验用于测试ESFramework网络通信框架服务端引擎的性能,测试程序使用ESFramework 4.0版本. 一.准备工作 测试的机器总共有3台,都是普通的PC,一台作为服务器,两台作为客户端. 作为服务器是PC配置如下: 操作系统:Windows Server 2003 Enterprise Edition SP2 CPU:Pentium Dual-Core CPU E5400 @ 2.70GHz 内存:2G   二.测试策略        本实验所采用的策略是这样的: (1)每个客

.NET可复用TCP通信层之消息分派器组件

上一篇主要讲到了Tcp通信层中的核心组件――Tcp组件的实现,Tcp组件是整个通信层的消息驱动源,甚至,可以将Tcp组件看作是我们整个服务器系统的消息驱动源,消息处理过程从这里引发.类似的消息驱动源还有发布的WebService接口.Remoting接口等.今天我们需要关注的是Tcp通信层中的"中央"组件――消息分派器组件ITcpReqStreamDispatcher,大家已经从前文的组件关系图中看到了消息分派器的大致位置和作用了,它是Tcp通信组件和消息处理器之间的"桥梁&

ESFramework ——成熟的C#网络通信框架(跨平台)

ESFramework网络通信框架是一套性能卓越.稳定可靠.强大易用的跨平台通信框架.也是.net平台首屈一指的成熟的C#网络通信框架.从最初的单纯的C#网络通信框架,历经10年,已经发展为支持包括安卓.IOS.Xamarin等多个平台的跨平台通信框架.其支持应用服务器集群.其内置了消息的收发与自定义处理(支持同步/异步模型).消息广播.P2P通道.文件传送(支持断点续传).心跳检测.断线重连.登录验证.在线用户管理.好友与群组管理.性能诊断等功能.基于ESFramework,您可以方便快捷地开

ESFramework介绍之(4)――消息拦截器INetMessageHook

    网络上传输的消息经常是经过加密和压缩,有的特定类型的消息可能还需要进行其它变形,ESFramework通过INetMessageHook对这些功能提供支持.需要说明的是,ESFramework对消息进行截获(Hook)处理有两种方式,一是仅仅Hook处理消息主体(Body),而不对消息头作任何变换:另一种方式是对整个消息(包括消息头和主体)都进行Hook处理.通常,第一种方式已经能够满足我们的大多数应用,并且效率也更高,如果应用有更特殊的要求,可以采用第二种方式.本文先介绍第一种方式,后

ESFramework 通信框架安全机制的设计与实现

      在分布式通信系统中,安全无疑是非常重要的.ESFramework通信框架提供了哪些安全保障了?由于ESFramework通信框架是应用层的开发框架,那么本文我们只讨论ESFramework通信框架在应用层涉及到的安全问题.如果黑客是在网络层或链路层进行攻击,位于应用层的系统是无能为力的.从应用层来说,安全的重要性主要体现在以下几个方面:(1) 防止恶意用户使用格式不正确的消息来试探服务端.(2) 防止通信的消息被恶意用户截获,或者,即使被恶意用户截获,也无法破解其内容.(3) 防止恶

网络通信应用开发利器!—— ESPlus —— ESFramework通信框架的增强库

概述 ESPlus 是基于网络通信框架ESFramework通信框架通信框架的增强库.为了更贴近实际应用,加快网络通信系统的开发,ESPlus在ESFramework通信框架原生功能的基础上,进行了再次封装,提供了大多数通信系统中经常用到的组件和功能.在这些功能中,最主要的是:自定义信息.基础API与状态通知.文件传送.P2P框架.好友关系.组关系.Rapid引擎.  1.自定义信息 使用通信框架最基础的需求就是收发信息,ESPlus底层已经为我们封装好了所有与信息收发相关的操作,我们只要调用I