ESFramework介绍之(7)-- 服务器代理IServerAgent

    (本文原作于2006.03.15,第一次修正于2006.06.06,修正后适用于ESFramework V0.3+)
    (本文是ESFramework对客户端开发的支持特性之一 ,如果要按顺序阅读,请转到ESFramework介绍())
    
    分布式系统的构建一般有两种模式,一是基于消息(如Tcphttp等),一是基于方法调用(如RPCWebServiceRemoting)。深入想一想,它们其实是一回事。如果你了解过.NETProxy,那么你会发现,方法调用和消息请求/回复实际上是可以相互转换的,.NETProxy的实现,就是在堆栈帧和消息之间相互转换的过程。关于这方面的详细论述可以参见《.Net本质论》一书。

  我觉得IServerAgent是我在开发ESFramework期间非常满意的一个想法,相信大家也会对它感兴趣的。因为它使得使用基于消息请求/回复的交互就像方法调用一样简单
    客户端与服务器之间的所有通信都可经过IServerAgent,包括要转发的P2P消息。它的主要目的是:
(1)屏蔽客户端与服务端之间的通信协议(Tcp/Udp),ITcpServerAgent、IUdpServerAgent
(2)可将异步的消息请求/回复转化为同步的方法调用。 

  ESFramework主要支持基于TcpUdpC/S系统,所以客户端和服务端之间是通过消息进行交互的。如果仅仅是客户端发出请求、服务器给出服务这种情况很容易处理,但是如果服务端有主动发消息给客户端的情况,事情就会变得稍微复杂。通常,客户端会有一个专门的接收线程来负责从网络接收数据,然后把接收的消息交给对应的处理器处理,或者,这个接收到的消息是个服务端给出的回复,那么这个回复就应该交给发出请求的请求者,但是对应的请求者在哪里了?这种回复消息与请求消息的匹配是比较繁琐的,特别是在上述服务端可以主动给客户端发送消息的情况下。为了简化这个过程,IServerAgent出现了,它用于客户端,像它的名字一样,可以把它当作服务器。IServerAgent的主要目的就是将消息请求/回复转换成方法调用,就像该接口定义的一样:

 

public   interface  IServerAgent
    {
        
///   <summary>
        
///  如果超时仍然没有回复,则抛出超时异常
        
///  如果dataPriority != DataPriority.CanBeDiscarded ,则checkRespond只能为false
        
///   </summary>      
        NetMessage CommitRequest(NetMessage requestMsg ,DataPriority dataPriority ,  bool  checkRespond);        
    }

    
public   enum  DataPriority
    {
        High ,
// 紧急命令
        Common , // 如普通消息,如聊天消息
        Low , // 如文件传输
        CanBeDiscarded  // 如视频数据、音频数据
    }

    

首先解释一下参数dataPriority的意义,dataPriority参数仅仅对Tcp协议起作用,当有多个请求要同时发送时,它决定了发送的优先级。CanBeDiscarded表明这个消息在网络繁忙时可以被抛弃,比如即时通讯的音频数据、视频数据等。关于这个数据发送的优先级机制的实现是ITcpAutoSender,这个组件会在后文中介绍。

    CommitRequest方法提交一个请求消息该给服务器,并返回一个回复消息给请求者。这就是一个方法调用!!!其间隐藏了通过网络将消息发送给服务器并从服务器获取结果的中间细节。这是怎么做到的?思路其实很简单,只是描述起来有些复杂。主要要解决两个问题,一是如何将请求消息与对应的回复匹配起来,二是CommitRequest从哪里找到匹配的回复。
    对于第一个问题,相信大家还记得IMessageHeader定义中有个CorrelationID属性,正如其名,这是一个随机数,每生成一个新的请求消息,就会产生一个随机数赋值给CorrelationID属性,由于随机数重复的可能性很小,所以可以把它当作是唯一的。这样一个随机数就唯一的标志了一个请求,当服务端收到这个请求后,就处理这个请求,并把回复消息的消息头中的CorrelationID属性设为与对应的请求消息的CorrelationID一样的值,这样,客户端收到回复消息后,就可以和对应的请求消息一一对应起来了。

  对于第二个问题的解释,就需要涉及到ESFramework中支持客户端开发的其它两个组件:EsbPassiveDataDealerIResponseManagerEsbPassiveDataDealer是客户端用户处理所有接收到的消息的处理器,而IResponseManager组件用于暂存所有的来自服务端的回复。对于每个接收到的消息,EsbPassiveDataDealer判断其是否为回复,如果是,则将其交给IResponseManager暂存。IResponseManager为暂存的每个回复都设置的生存期TTL,如果回复在IResponseManager中的时间超过了这个TTL,则会被删除。

  你也许已经想到第二个问题的解决方法了。是的,CommitRequest方法将请求发送到网络之后,就定时从IResponseManager中寻找CorrelationID为请求消息头的CorrelationID值的回复消息,如果找到,就返回它,否则就等待循环,直至超时抛出TimeoutException异常。下面给出IResponseManager的接口定义:
   

    public   interface  IResponseManager
    {
        
void  Initialize() ;

        
void  PushResponse(NetMessage response) ;
        NetMessage PopRespose(
int  correlationID , int  serviceKey) ;   // 立即返回
        NetMessage PickupResponse( int  serviceKey , int  corelationID) ; // 在TimeoutSec时间内不断的PopRespose

        
///   <summary>
        
///  ResponseTTL 如果一个回复在管理器中存在的时间超过ResponseTTL,则会被删除。如果ResponseTTL为0,则表示不进行生存期管理
        
///   </summary>         
         int  ResponseTTL{ set  ;}  // s

        
///   <summary>
        
///  如果在TimeoutSec内,仍然接收不到期望的回复,则抛出异常。取0时,表示不设置超时
        
///   </summary>
         int  TimeoutSec{ set  ; }     
    }

      IServerAgent的具体实现包括TcpServerAgent和UdpServerAgent,分别支持Tcp协议和Udp协议的客户端开发。从它们的接口定义中可以看到它们都借助于IServerAgentHelper实现自己。

    public   interface  IServerAgentHelper
    {
        IEsbLogger          EsbLogger{
set  ;  get  ;}
        IContractHelper   ContractHelper{
set  ;  get  ;}
        INetMessageHook   NetMessageHook {
set  ;  get  ;}
        IPassiveHelper    PassiveHelper {
set  ;  get  ;}

        IResponseManager  ResponseManager{
set  ; get  ;}    

        ISingleMessageDealer SingleMessageDealer{
set  ;  get  ;}        

        IMessageDispatcher ConstructDispatcher() ;        
    }

    我们要特别注意其ConstructDispatcher方法,该方法构建了一个客户端比较常用的消息分配器实例。在介绍IMessageDispatcher时,我们讲过,客户端通常不需要对消息Spy,仅仅需要Hook就可以了,所以IServerAgentHelper正是通过对各组件的组装做到了这一点:

        public  IMessageDispatcher ConstructDispatcher()
        {
            
// NakeDispatcher
            EsbPassiveDataDealer dealer      =   new  EsbPassiveDataDealer( this .responseManager , this .passiveHelper , this .singleMessageDealer) ;
            EsbPassiveDealerFactory factory 
=   new  EsbPassiveDealerFactory(dealer) ;
            NakeDispatcher nakeDispatcher   
=   new  NakeDispatcher() ;
            nakeDispatcher.ContractHelper   
=   this .contractHelper ;
            nakeDispatcher.DataDealerFactory
=  factory ;

            
// MessageDispatcher
            IMessageDispatcher messageDispatcher  =   new  MessageDispatcher() ;
            messageDispatcher.ContractHelper     
=   this .contractHelper ;
            messageDispatcher.NetMessageHook     
=   this .netMessageHook ;
            messageDispatcher.NakeDispatcher     
=  nakeDispatcher ;

            
return  messageDispatcher ;
        }

    在IServerAgent的基础之上,我们就可以从一个新的角度来设计客户端的结构的,那就是采用和功能服务器一样的插件方式。在ESFramework的支持下,我们的应用开发变得非常简洁和简单,所要做的主要内容就是开发服务端的“业务功能插件”和对应的客户端的“PassiveAddin”(客户端插件)。如果我们的应用已经发布投入使用,而此时用户要求添加一项新的业务,那将是非常简单的事情,那就是开发一个实现了新业务的功能插件动态加载到功能服务器中、再开发一个对应的客户端插件动态加载到客户端中,这样就可以了。服务器不用重编译、甚至不用停止服务;客户端也不用重编译、甚至不用停止使用。一切都是在运行中动态完成的。

    这是如何做到的?请关注本系列文章。

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

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
iWebClient2003是一个网络文档管理软件。 由服务器端和客户端插件组成。 许可协议 =============================================================================== 在使用前,请认真阅读下列条款,你一旦安装、使用本程序,既表示你同意接受本协议。 1. 未经金格科技授权,你不得复制本程序或再分发或提供下载 2. 在测试使用过程中对你的计算机系统、网络系统所造成的直接或间接的损坏, 金格科技不承担任何责任。 3. 你不得对本程序进行修改或破解或反编译 4. 未经金格科技授权许可,你不得将本软件用于商业目的 =============================================================================== 功能简: =============================================================================== 1、实现了通过IE刘览器,打开服务器上的文件,然后进行编辑与修改,完成后,可以 保存到服务器上去。 2、本程序能够打开任何服务器上的文件。 注:演示版有限制。如要正式版,请与作者联系。 文件组成: =============================================================================== 1、 iWebClient2003iWebClient2003.asp 2、 iWebClient2003iWebServer2003.asp 3、 iWebClient2003iWebClient2003.ocx 4、 iWebClient2003iMsgServer2003.dll 5、 iWebClient2003软件说明.txt 6、 iWebClient2003Document演示文件目录 操作环境: =============================================================================== 服务器端: Microsoft Windows 2000 & IIS5.0 以上 客户机端: Microsoft Internet Explorer 5.0 以上 安装说明: =============================================================================== 1、将文件iWebClient2003.rar在服务器上解压缩后,您将看到如上述文件组成列表 2、将iWebClient2003文件目录在IIS中映射成一个虚拟目录iWebClient2003 3、请用RegSvr32 盘符:iWebClient2003iMsgServer2000.dll命令注册iMsgServer2000.dll 组件您也可以用组件管理工具来注册 4、打开IE浏览器,键入http://localhost/iWebClient2003/iWebClient2003.asp,你将看到 一个页面。 5、选择你要编辑的文档,点击打开文档按钮,系统会自动用你计算机上的软件相关软件打开, 你可以进行编辑,然后存盘,回到IE页面上,点击保存文档按钮,文件便保存在服务器上了, 你可再次打开文档,看看是否真的完成了编辑功能。 编程接口 =============================================================================== 客户端iWebClient2003.ocx ------------------------ 属性 1、WebUrl 服务器应用程序路径如http://www.goldgrid.com/iwebserver.asp 2、HttpPort 服务器访问端口 如80或8080 3、UserName 如果使用代理服务器,则填写代理服务器验证的用户名 4、PassWord 如果使用代理服务器,则填写代理服务器验证的用户密码 5、ProxyServer 如果使用代理服务器,则填写代理服务器服务器名或地址 6、ProxyPort 如果使用代理服务器,则填写代理服务器端口 函数 1、SetMsgByName(FieldName,FieldValue) 设置变量信息,以便发送给服务器应用程序 2、GetMsgByName(FieldName) 取得从服务器上返回的信息 3、MsgTextClear 清除所有取得或设置的文本信息 4、MsgFileLoad(FileName) 装入文件,以便发送给服务器应用程序 5、MsgFileSave(FileName) 保存服务器返回的文件 6、MsgFileSize 取得服务器返回的文件大小 7、MsgFileClear 清除所有文件内容 8、MsgSend 将所设置的信息发送给服务器应用程序 9、MsgError 取得服务器应用程序的返回信息 10、MkDirectory(DirName) 在客户端建立目录 11、RmDirectory(DirName) 在客户端删除目录 12、WebExecute(FileName,Paramer,FilePath,WinStatus) 在客户端运行指定的文件 FileName 运行文件名, Paramer 参数, FilePath 工作目录, WinStatus 打开窗口的状态 13、WebDeleteFile(FileName) 在客户端删除文件 14、WebCheckFile(FileName) 在客户端检测文件是否存在 15、WebGetFile(LocalFile,RemoteFile) 下载服务器上文件并保存在本地, LocalFile 本地文件名, RemoteFile服务器文件名 16、WebPutFile(LocalFile,RemoteFile) 上传本地文件并保存到服务器上, LocalFile 本地文件名, RemoteFile服务器文件名 服务器端iMsgServer2000.dll -------------------------- 1、SetMsgByName(FieldName,FieldValue) 设置变量信息,以便返回给客户端应用程序 2、GetMsgByName(FieldName) 取得从客户端上发送的信息 3、MsgTextClear 清除所有取得或设置的文本信息 4、MsgFileLoad(FileName) 装入文件,以便发送给客户端 5、MsgFileSave(FileName) 保存客户端发送的文件 6、MsgFileSize 取得客户端发送的文件大小 7、MsgFileClear 清除所有文件内容 8、MsgError 设置返回客户端的错误信息,如果没有错误,这个值为空 9、MsgVariant 返回给客户端的所有信息 客户端与服务器端通讯 ------------------------ 采用请求应答方式进行,客户端只发送3种操作命令给服务器应用程序,他们分别是 WEBGETFILE 下载服务器文件 WEBPUTFILE 上传客户端文件 MSGSEND 发送一般消息(消息的其他内容在客户端用SetMsgByName设置) 具体调用方式请参考iWebServer2000.asp文件 开发编程: =============================================================================== 公司: 江西金格网络科技有限责任公司 网站: http://www.goldgrid.com 邮件: [email protected]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值