基于.NET Remoting的三层分布式应用程序兑现
摘要:文中主要探讨基于三层分布式结构来开发数据库应用程序的具体过程和方法。首先,介绍三层分布式结构的体系结构和工作原理;然后介绍.NET Remoting远程处理框架和ADO.NET数据访问技术。最后通过一个简单分布式应用程序实例进一步阐述,说明三层分布式结构可以大大提高分布式应用程序的运行效率和安全性。
关键词:.NET Remoting;分布式应用程序;VB.NET
Realization of Three-tier Distributed Application Based on.NET Remoting
WU Li
(Jiangsu College of Information Technology,Wuxi 214100,China)
Abstract:Mainly discusses the process and method of exploder database application base on three-tier distributed architecture.First,introduces the architecture and principle of three-tier distributed architecture,Second,introduces.NET Remoting Framework and the technology of data accessing:ADO.NET.Finally,explain that it can advance the efficiency and security of distributed application by giving an example of distributed application processing.
Keys words:.NET Remoting;distributed application;VB.NET
1引言
传统的客户端/服务器端(C/S)结构的数据库软件开发模式曾经得到非常普及,但随着计算机往来的不断发展以及业务对象技术的出现,两层C/S结构也暴露出其构架上的诸多缺陷。发展成将两层客户机/服务器的体系结构的应用逻辑从用户端分离出来,形成多层客户机/服务器体系结构。本文以三层分布式结构为框架,举例说明在.NET环境下基于.NET Remoting和ADO.NET数据访问技术,配合VB.NET编程语言,实现对分布式数据库应用程序的具体过程。
2分布式应用程序的概念和结构
分布式应用程序将整个应用程序的处理分成几个部分,分别在不同的机器上运行的程序。
“分布”一词包含两层含义:地理上的分布和数据处理的分布。而在网络上,分布式应用对用户来说应该是透明的,即使是在不同的位置,企业不同的业务部门也应该协调分工合作。
传统的C/S结构一般分为两层:客户端和服务器端。其基本工作原理是:客户程序向数据服务器发送SQL请求,服务器返回数据和结果。这种结构在近十年内不但得到广泛运用,而且相当成功。然而随着信息系统结构的复杂和规模的日益扩大,两层C/S结构也暴露出其构架上的缺陷:由于客户端和服务器端直接连接,服务器将消耗部分系统资源用于处理与客户端的连接工作,从而导致系统整体运行效率的大幅降低。以及程序移植性差和系统可靠性的极大隐患等。为此将两层客户机/服务器的体系结构的应用逻辑从用户端分离出来,形成多层客户机/服务器体系结构,本文以三层分布式结构为例说明。
三层分布式结构分为表示层、逻辑层和数据层,如图1所示。表示层提供给用户一个可视化界面,通过界面层,用户可以输入数据或获取数据,界面层同时也提供一定的安全性,确保用户不会看到机密的信息。逻辑层是界面层和数据层的桥梁,它响应界面层的用户请求执行任务并从数据层获取数据,并将必要的数据传送给界面层。逻辑层包含封装了系统应用逻辑的业务对象,应用系统的大部分计算工作在此完成。逻辑层维护同数据库的连接,采用“数据缓冲”和“代理连接”,保证只有较少两的拥护数据连接,逻辑层拥有自己的内存和CPU,并且可根据不同应用需要进行分布式计算,所以能够提供较高性能的数据库应用。数据层定义、维护数据的完整性、安全性,它响应逻辑层的请求,访问数据,这一层通常有大型的数据库服务器实现。
.NET Remoting是内置到Visual Studio.NET公共语言运行库中的框架。Remoting基础结构由代理、通道和消息组成。代理是指模仿远程对象的本地对象,它提供了与远程对象完全一致的方法和属性。要实现指定方法的代理,通常需要将调用传给通道对象。 通道对象代表了与远程应用程序的连接。每个通道对象都包含一个将方法调用转换为已知格式消息的格式化程序对象,并将消息发送到服务器上,客户端通道对象的镜像在服务器上侦听请求。消息是用于服务器和客户端进行通信所创建的信息包。其体系结构如图2所示。 其基本原理如图1所示,首先,客户端通过通道访问服务器端对象,以获得服务器端对象的代理。服务器端对象也即通常所说的远程对象,使用时是通过跨应用程序边界传递对象引用获得该远程对象的代理。对于客户程序来说,代理提供了与远程对象完全一样的方法和属性。当代理的方法别调用时,就会创建消息,通过使用格式化程序类,将这些消息串行化并发送到客户通道中。客户通道和服务器通道进行通信,以通过网络传输消息。服务器通道则使用格式化程序并行化消息,从而将方法发送给远程对象。通过代理,客户端应用程序就可以像使用本地对象一样来操作远程对象。 通道是一种远程框架,它隐藏了在客户和服务器应用程序间通信时所使用的底层协议。通道对象最终用来将每个方法调用从客户端传送到服务器端,并将其返回值回传给客户端。每个通道对象都包含了一个格式化程序对象,该对象将方法调用串行化为适用于底层网络协议的有效负载。.NET Remoting提供了HTTP和TCP两种通道实现方式。HTTP通道利用HTTP协议提供连接性,在Web服务器和Web浏览器间也使用HTTP协议。在每个应用程序域中,对于指定类型的通道,运行库只允许注册一个通道。因此,在一个应用程序域中,不能注册两个HTTP通道或TCP通道。 .NET Remoting中通过通道(channel)来实现两个应用程序域之间的对象通信。Remoting的通道主要有两种:Tcp和Http。在.NET中,System.Runtime.Remoting.Channel中定义了IChannel接口。IChannel接口包括了TcpChannel通道类型和Http通道类型。它们分别对应Remoting通道的这两种类型。通道对象代表了到远程应用程序的连接。每个通道对象还包含格式化程序对象,将方法调用转换为已知格式的消息。 远程对象通常包含了业务逻辑的具体实现,它被创建并存储在服务器端,被远程客户端代理。远程对象和其它对象的区别是远程对象支持引用调度,因此必须从System.MarshalByRefObject继承。Remoting有以下两种对象激活模式: (1)服务器端激活模式(Server Activated Object):它是由服务器负责远程对象的生命周期,包括单件模式(Singleton)和单一调用模式(SingleCall)。 Singleton模式是一种共享模式,任何时候都只有一个Singleton模式配置的类型实例处于活动状态。如果没有其它实例,客户端首次访问某实例时激活该实例。Singleton实例会处理所有后来的客户端访问请求,不管是同一客户端还是其他客户端。Singleton实例可以在方法调用中维持状态。它适用于此种情形:如果一个对象的实例构造很费时,而具体的业务处理却不必耗费多少时间;SingleCall是一种无状态编程模型,Remoting基础结构会为客户端的每个方法调用激活一个该类型的新实例。方法调用返回之后,基础结构会让那个远程对象实例在下次垃圾回收的时候可再循环使用。对于服务器激活对象,远程对象的透明代理将在客户端应用程序域中生成并返回到客户端,这时不执行任何远程调用。只有在客户端调用远程对象的某个方法时,该远程对象才会被激活。 (2)客户端激活模式(Client Activated Object):它是由客户端负责管理远程对象的生命周期。客户端激活对象受基于租用的生存期管理器的控制,这种管理器确保了租用期满时对象可被回收。与如何处理服务器端激活类型相比,Remoting基础结构激活每个对象实例的时候会给每个客户端激活的类型指派一个URI。客户端激活类型的实例可以在方法调用中保持活动状态。 在开发远程对象组件时,可以通过使用配置文件来简化代码并提高配置的灵活性。例如,如果一个远程对象其激活模式可能为Singleton或SingleCall模式,其通道实现方式可能为HTTP或TCP。要满足这样的需求,只需要在配置文件中动态指定,而无需修改源程序再重新编译(具体可参见后面的实例)。 远程对象元数据的部署,通常将远程类型分成接口和实现,并将每个接口和实现编译成单独的程序集,然后将接口程序集部署到客户端,在服务器端保留完整实现的程序集。由于远程对象通常包含了业务逻辑的具体实现,通过部署接口可以防止一些敏感信息或私有代码被窃取。 设计目标:实现电子图书馆远程数据查询功能的分布式应用程序,由包含业务逻辑的远程对象以及服务器端和客户端应用3部分组成;远程对象:处理具体的书籍查询业务,创建数据库连接并组装数据集,是一个可被客户代理的Windows类库;服务器应用:创建通信管道,注册业务对象,提供远程对象服务;客户端应用:调用远程对象,实现远程查询等操作;示例程序使用VB.NET语言设计,并经测试正确。 操作环境:Windows 2000+IIS 6.0+SqlServer 2000+Microsoft Studio.NET 2003。 (1)创建业务逻辑的远程对象、服务器端及客户端应用。启动Visual Studio.NET并创建名为LibraryMng解决方案;添加名为ServerClassLibrary(远程对象)的类库项目;添加名为ServerApp(服务器端)和ClientApp(客户端)的Windows Application项目;右击解决方案并选择Properties,选择多个活动项目。 (2)向ServerClassLibrary项目中ManagerBaseClass.vb文件中添加如下代码: Public Class ManagerBaseClass Inherits System.MarshalByRefObject End Class 向DataManagerClass.vb文件添加如下代码: Public Class DataManagerClass Private m_ConnObj As Data.OleDb.OleDbConnection Private m_LastError As String Public ReadOnly Property ConnObj()As Data.OleDb.OleDb- Connection Get If m_ConnObj Is Nothing Then m_ConnObj=New System.Data.SqlClient.SqlConnection("Serv- er=Localhost; Database=Librarydatabase;Integrated security=true) End If Return m_ConnObj End Get End Property Public Function Connect()As Boolean Try If ConnObj.State<>ConnectionState.Open Then ConnObj.Open() End If Return True Catch ex As Exception m_LastError="连接数据库失败:"+ex.Message Return False End Try End Function Public Shared DatabaseName As String End Class 向BookMngClass.vb文件中填加代码: <Serializable()>Public Class BookInfo Public BookID As String Public BookName As String End Class Public Class BookManager Inherits ManagerBaseClass Private m_DataManager As DataManagerClass Public Sub New() MyBase.New() m_DataManager=New DataManagerClass End Sub Public Shared Sub RegisterSelf()System.Runtime.Re- moting.RemotingConfiguration.RegisterWellKnownServiceType (GetType(ServerClassLibrary.LibraryMng.BookManager),"Book- Manager", Runtime.Remoting.WellKnownObjectMode.Singleton) End Sub Public Function GetAllBookInfo(ByRef ErrStr As String)As System.Collections.ArrayList Dim ResultList As New System.Collections.ArrayList Dim CmdObj As New System.Data.OleDb.OleDbCommand("Se- lect*from BookTable") CmdObj.Connection=m_DataManager.ConnObj Dim Reader As System.Data.OleDb.OleDbDataReader Dim BInfo As New BookInfo Dim FieldInde xs(11)As Integer Dim IndexInited As Boolean=False Reader=CmdObj.ExecuteReader While Reader.Read If Not IndexInited Then FieldIndexs(0)=Reader.GetOrdinal("FBookID") FieldIndexs(1)=Reader.GetOrdinal("FBookName") IndexInited=True End If BInfo.BookID=Reader.GetString(FieldIndexs(0)) BInfo.BookName=Reader.GetString(FieldIndexs(1)) Reader.Close() Reader=Nothing Return ResultList End Function End Class 编译该项目生成ServerClassLibrary.dll,用于在服务端提供远 程对象服务。 (3)为ServerClass项目引用System.Runtime.Remoting和 ServerClassLibrary,同时向其各自窗体New()文件中添加以下代码: ServerClassLibrary.LibraryMng.DataManagerClass.Database- Name="Database.mdb" m_ServerObjectMng=New ServerClassLibrary.LibraryMng. ServerObjectMngClass m_ServerObjectMng.RegistServerObjects() Dim chl As System.Runtime.Remoting.Channels.Tcp.TcpChan- nel chl=New System.Runtime.Remoting.Channels.Tcp.TcpChannel (9494) System.Runtime.Remoting.Channels.ChannelServices.Register- Channel(chl) 并在ServerClass项目中创建服务端界面MainForm.vb文件 Public Class MainForm Inherits System.Windows.Forms.Form Private m_ServerObjectMng As ServerClassLibrary.LibraryMng. ServerObjectMngClass Private Sub MinToTrayButton_Click(ByVal sender As System. Object,ByVal e As System.EventArgs)Handles MinToTrayButton.Click MainNotifyIcon.Visible=True Visible=False End Sub End Class (4)为ClientClass项目引用System.Runtime.Remoting和 ServerClassLibrary,同时向其各自窗体New()文件中添加以下代码: Dim chl As System.Runtime.Remoting.Channels.Tcp.TcpChannel chl=New System.Runtime.Remoting.Channels.Tcp.TcpChannel System.Runtime.Remoting.Channels.ChannelServices.Register- Channel(chl) 并在ServerClass项目中创建客户端界面BookMngForm.vb文件,填加一个文本框,一个查询按钮,一个ListView控件。 Public Class BookMngForm Inherits System.Windows.Forms.Form Private BookMgr As ServerClassLibrary.LibraryMng.BookManag- er Private BookList As System.Collections.ArrayList Private m_LastError As String Private Sub BookMngForm_Load(ByVal sender As Object,By- Val e As System.EventArgs) Handles MyBase.Load BookMgr=ServerClassLibrary.LibraryMng.BookManager.Get- Manager(m_LastError) If BookMgr Is Nothing Then End If Try Dim ErrStr As String BookList=New ArrayList(BookMgr.GetAllBookInfo(ErrStr)) Catch ex As Exception m_LastError="获取图书列表失败:"+ex.Message End Try End Sub Private Sub Button1_Click(ByVal sender As System.Object,By- Val e As System.EventArgs)Handles Button1.Click Dim BName As String Dim i As Integer BName=TextBox1.Text Dim Books As New System.Collections.ArrayList For i=0 To BookList.Count-1 If String.Compare(CType(BookList(i),ServerClassLibrary.Li- braryMng.BookInfo).BookName,BName)=0 Then Books.Add(BookList(i)) End If Next If Books.Count=0 Then DialogUtilsClass.ErrorDlg("指定图书没有找到") Else Dim Item As System.Windows.Forms.ListViewItem Dim BInfo As ServerClassLibrary.LibraryMng.BookInfo For i=0 To Books.Count-1 BInfo=CType(Books(i),ServerClassLibrary.LibraryMng.BookInfo) Item=BookListView.Items.Add(BInfo.BookID) Item.SubItems.Add(BInfo.BookName) Next End If End Sub End Class 使用.NET Remoting技术结合ADO.NET能够高效、可靠地建立分布式数据应用程序的解决方案。其优势在于:通过使用.NETRemoting框架能够方便地解决数据、命令远程传递问题;而通过ADO.NET对数据库可以方便地进行操作,使分布式数据库系统中对数据库的各种操作更加高效、可靠,同时易于解决数据的完整性和一致性问题。 [1]何丽,方英兰,张勇.Visual Basic.NET分布式应用程序开发[M].北京:清华大学出版社,2004. [2]梁普选,张宝华,李国昌..NET远程处理构架及分布式对象处理[J].河北工业科技,2004,21(6):35-38. [3]马保国,王文丰,侯存军,钱方正.基于.NET Remoting的分布式系统实现[J].计算机技术与发展,2006,16(3):50-52. [4]McLean S,Naftel J,Williams K.张昆琪,等译.Microsoft.NETRemoting权威指南[M].北京:机械工业出版社,2003. 本文章来源于互联网,主要用于技术交流并服务广大研究人员并未用于商业用途
3.NET Remoting体系结构和基本工作原理
3.1.NET Remoting体系结构
3.2基本工作原理
3.3几个核心对象
3.3.1通道对象
3.3.2远程对象
3.4配置文件和远程对象的部署
3.4.1配置文件
3.4.2远程对象部署
4基于Remoting的分布式应用应用程序实现
5结束语
参考文献: