基于Proxy模式的远程处理框架研究
2013-04-14武夷学院数学与计算机系福建武夷山354300
(武夷学院数学与计算机系,福建 武夷山354300)
在分布式应用系统开发中,基于面向服务体系架构(Service-Oriented Architecture,SOA)的软件架构已经成为主流。JavaRMI、EJB、CORBA(Common Object Request Broker Architecture,公共对象请求代理体系结构)和Microsoft的 WCF(Windows Communication Foundation,视窗通信基础)、.NET Remoting、Web Service等都可以用于SOA系统的开发[1-5]。以上技术作为成熟的机制,经过层层包装,隐藏了技术细节,在方便开发人员使用的同时,也存在一个问题:开发人员知道如何使用框架进行开发,但无法理解框架原理及底层运作细节,对于一些特殊的编程需求,难以对框架进行有效扩展。为此,笔者提出了一种基于Proxy模式的远程处理框架,其在局域网的应用中编程模型简单,框架原理易于理解,且能够实现高速有效的远程方法调用。
1 Proxy模式
Proxy模式有助于跨越障碍进行数据访问[6]。Proxy模式的意图是为其他对象提供一种代理以控制对这个对象的访问[7]。其适用场合之一就是远程代理(Remote Proxy)模式。远程代理为一个对象在不同的地址空间提供局部代表,隐藏了一个对象存在于不同地址空间的事实。Proxy模式的结构如图1所示,其参与者中,Proxy对象保存一个引用使得代理可以访问实体RealSubject对象。若为远程代理,则Proxy对象负责对请求及其参数进行编码,并向不同地址空间中的实体发送已编码的请求。
图1 Proxy模式结构
2 远程处理框架
远程处理框架从功能上应当使跨应用程序边界(可以跨应用程序域、跨进程、跨机器乃至跨网络)的应用程序之间能够进行通信。为便于叙述,将参与通信的应用程序区分为客户端和服务器端。通过远程处理框架,客户端能够以与调用本地方法相同的方式调用服务器端的远程服务对象的方法。笔者提出的远程处理框架包含代理和远程处理2个组件,其结构如图2所示。
图2 基于Proxy模式的远程处理框架
通过使用代理组件,客户端获得TransparentProxy(透明代理),TransparentProxy调用RealProxy(真实代理)的Invoke方法,所以,重写Invoke方法是创建代理对象的关键。Invoke方法应当包括:向服务器发出链接请求;将调用请求封装成消息,向服务器发送该消息;等待并接收返回消息;将消息返回代理对象。因透明代理与远程服务对象类型一致,故客户端调用代理上的方法与调用远程服务对象的方法相同。
现有的各类远程处理框架中,服务器一般充当宿主,即只发布远程服务对象,其余的工作都由远程处理框架完成。框架中的远程处理组件遵循此原则,其功能包括监听客户端链接请求、根据客户端的调用请求调用服务对象的方法、将方法调用的结果发送回客户端的代理对象等。
3 远程处理框架的实现
笔者所提出的远程处理框架采用Remote Proxy模式,由代理组件和远程处理组件构成。代理组件ProxyClass从抽象类RealProxy派生,其通过持有远程服务接口IServerClass可在客户端中以本地化的方式调用远程服务对象的相关方法;远程处理组件发布远程服务对象,并通过Socket监听来自客户端的链接请求,根据请求内容进行方法调用并返回处理结果。
3.1 Remote Proxy模式结构
Remote Proxy模式与传统Proxy模式最大的区别在于代理类ProxyClass没有实现公共接口IServerClass,而是派生于RealProxy类(见图3)。RealProxy是.NET框架提供的用于实现代理功能的抽象类,其包括抽象方法Invoke,Invoke方法定义如下:
public abstract IMessage Invoke(IMessage msg);
其中,类型为IMessage的参数msg包含了有关方法调用的信息:对象标识、方法名和参数列表等。RealProxy通过Invoke方法持有远程服务接口的信息。ProxyClass因派生于RealProxy而获得了远程服务接口,并通过Invoke方法实现了Remote Proxy模式的意图:对方法调用请求信息进行编码,并向不同地址空间中的实体发送已编码的请求[6]。
图4 远程处理框架通信流程
3.2 代理组件设计
代理组件是远程处理框架中应用于客户端的重要组件,客户端通过代理组件实现方法调用消息的封装、传输,并接收远程服务对象调用结果的返回消息(见图4)。
创建任何代理类都必须继承于抽象类RealProxy[7]。为了获取远程对象的透明代理,可通过调用代理类的GetTransparentProxy方法。用透明代理对象调用远程对象的方法时,将自动调用被重写过的Invoke方法。重写Invoke方法的主要步骤如下:①生成远程对象方法的调用消息。以下代码中,RemoteMethodInfo类是自定义的,用于表示远程对象方法的调用消息:
②将调用消息序列化到内存流。这里需要用到MemoryStream类,该类定义的流对象可以将对象状态序列化到内存中。③与发布远程对象的服务器建立链接。用TcpClient类的构造函数进行到服务器的链接,此处需提供主机名和端口号。④将步骤②处理结果发送到服务器。TcpClient类的GetStream方法返回一个NetworkSteam类对象,该对象用于对Internet中的数据进行发送或接收。⑤等待服务器响应。DataAvailable属性用于确定是否可以读取数据,如果可以在NetworkSteam上读取数据,则为true,否则为false。⑥从服务器接收数据。当服务器将调用结果返回时,将流上的数据读取到字节数组_buffer中,并用其构建内存流对象,最后将接收到的数据反序列化以重构对象。⑦根据调用结果构造返回消息。构造返回消息就是创建ReturnMessage对象,该对象将被RealProxy类的其他方法解包装,获得真正的调用结果。
3.3 远程处理组件设计
远程处理组件是远程处理框架的核心,服务器端使用远程处理组件注册信道,发布远程服务对象,并处理来自客户端的调用请求[8]。远程处理组件结构如图5所示,其中RegisterChannel方法实现信道注册功能,Register RemoteObject方法实现远程服务对象注册功能,StartServers方法对每个注册信道启动一个线程进行处理,ChanelProc方法具体负责与客户端的通信,MyChannel和MyRemoteObj是自定义类,分别代表信道对象和远程服务对象。
图5 远程服务组件结构
1)信道注册功能 服务器注册信道时,为每个信道命名。信道注册方法中,首先检测信道名称,若信道名称不存在,则创建信道并分配端口号,将该信道添加到已注册的信道集合中。
2)远程服务对象注册功能 服务器注册远程对象时,为每个远程对象指定一个URI。远程对象注册方法中,首先检测该URI是否已存在,若该URI不存在,则注册该远程对象并将其添加到已注册的远程对象集合中。
3)启动注册信道 对于每一个已注册的信道启动一个线程池,利用QueueUserWorkItem方法将信道监听处理方法ChannelProc作为回调方法排入队列等待执行,channel对象作为参数传递给ChannelProc方法。
4)信道处理方法 信道处理方法首先启动监听。利用Socket对象接收客户端连接请求,并通过序列化和反射机制,用所接收的数据创建远程服务对象,调用对应方法,获取结果,反序列化后发送回客户端[8]。其详细步骤如下:①接收用户请求,AcceptSocket方法用于接收来自客户端的连接请求,并返回一个Socket对象;②接收并缓存数据,Receive方法接收客户端的请求数据,并将所接收数据存入到缓冲区Buffer中;③将数据反序列化为调用请求对象;④获取远程服务对象标识;⑤获取实际的远程服务对象,ActiveObj是MyRemoteObj中定义的只读属性,其通过反射机制创建了远程服务对象;⑥调用远程对象的相应方法并获得结果;⑦将调用结果序列化并发送到客户端。
4 应 用
为验证以上远程处理框架的有效性,将框架相关组件应用于高校大学生素质拓展学分管理系统。部分高校要求学生需积极参加各类课外活动以获取素质拓展学分,学分类型分为学术活动、文体活动等6类,规定每类需修满1学分,总分不低于10学分方可毕业。一般情况下,每位学生的学分验证信息约60~100条,每学期增加的信息记录约10万条。系统共有学生、院系教务管理人员和校素质拓展中心管理人员3类用户:学生通过浏览器登录系统,可提交学分验证信息和查看本人学分,院系教务管理人员通过客户端登录远程服务器,审核信息并提交数据。系统用C#语言开发,用SQLServer2005作为数据库服务器。下面以院系教务管理人员远程登录为例,相关组件部署如表1所示。
表1 远程处理框架组件及部署
4.1 远程服务接口与服务类
为便于部署,将服务接口与服务类分放在2个不同的文件中,客户端只需持有服务接口即可。这样设计的优势很明显,只要接口不变,服务类的具体实现的变化就不会对客户端产生影响,保证了客户端的稳定性(IServerClass声明了服务接口,ServerClass实现IServerClass(见图3))。其中Authentication方法对教务管理人员提供的UID和密码进行验证并返回验证结果。
4.2 发布远程服务对象
通常,在远程处理框架中,服务器端一般是作为远程服务对象的宿主程序。服务器端通过以下步骤发布远程服务对象:使用远程处理组件,先注册一个信道,再注册一个远程服务对象,之后,利用线程池接受客户端的服务调用请求并进行处理。代码如下:
4.3 客户端
客户端通过代理组件获取远程服务对象的透明代理后,将以使用本地对象的方式使用远程服务对象。院系教务管理人员在进行素质拓展学分的管理前需登录到服务器进行身份验证,方法如下:
5 结 语
研究了一种远程处理框架,通过Remote Proxy模式将框架分解成代理组件和远程处理组件,在组件设计中,涉及序列化机制、反射机制等.NET框架中的重要技术,并基于Socket实现了远程服务对象方法调用信息的网络通信过程。最后,将其应用于高校大学生素质拓展学分管理系统,客户端通过代理组件能够以调用本地对象成员函数的方式调用远程服务对象的函数。当然,与成熟的分布式系统构建技术相比,笔者所提出的框架还有其不足之处,如发布对象的宿主机制还不够完善,无法采用配置文件等。
[1]李海闻,宁敏,林福良,等 .一种基于CORBA的分布式应用模型 [J].计算机系统应用,2010,19(2):33-34.
[2]刘丹,程晓,侯德林 .一种基于RMI的分布式架构设计 [J].计算机应用与软件,2007,24(9):207-208.
[3]钟涵,李志蜀,王汾雁,等..NET Remoting和Web Service结合的分布式应用设计与实现 [J].计算机应用,2007,27(6):213-214.
[4]赵庆霞,孙建伶 .基于WCF的服务缓存设计与研究 [J].计算机工程与设计,2010,31(14):3151-3152.
[5]Lowy J.WCF服务编程 [M].张逸,徐宁 译 .北京:机械工业出版社,2008:14-16.
[6]Martin R C,Martin M.敏捷软件开发:原则、模式与实践(C#版)[M].邓辉,孟岩 译 .北京:人民邮电出版社,2008:377-381.
[7]Gamma E,Helm R,Johnson R,et al.Design patterns elements of reusable object-oriented software [M].New York:Adison-Wesley,1995:233-234.
[8]飞思科技产品研发中心 .精通.NET核心技术——高级特性 [M].北京:电子工业出版社,2002:202-211.