|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
无论谁倒了对双方阵营的粉丝们也是有害无益。程序 1、Remoting基本
甚么是Remoting,简而言之,我们能够将其看做是一种散布式处置体例。从微软的产物角度来看,能够说Remoting就是DCOM的一种晋级,它改良了良多功效,并极好的交融到.Net平台下。Microsoft?.NETRemoting供应了一种同意工具经由过程使用程序域与另外一工具举行交互的框架。这也恰是我们利用Remoting的缘故原由。为何呢?在Windows操纵体系中,是将使用程序分别为独自的历程。这个历程构成了使用程序代码和数据四周的一道界限。假如不接纳历程间通讯(RPC)机制,则在一个历程中实行的代码就不克不及会见另外一历程。这是一种操纵体系对使用程序的回护机制。但是在某些情形下,我们必要跨过使用程序域,与别的的使用程序域举行通讯,即穿越界限。在Remoting中是经由过程通道(channel)来完成两个使用程序域之间工具的通讯的。如图所示:
起首,客户端经由过程Remoting,会见通道以取得服务端工具,再经由过程代办署理剖析为客户端工具。这就供应一种大概性,即以服务的体例来公布服务器工具。远程工具代码能够运转在服务器上(如服务器激活的工具和客户端激活的工具),然后客户端再经由过程Remoting毗连服务器,取得该服务工具并经由过程序列化在客户端运转。
在Remoting中,关于要传送的工具,计划者除必要懂得通道的范例和端标语以外,无需再懂得数据包的格局。但必需注重的是,客户端在猎取服务器端工具时,并非取得实践的服务端工具,而是取得它的援用。这既包管了客户端和服务器端有关工具的松懈耦合,同时也优化了通讯的功能。
1、Remoting的两种通道
Remoting的通道次要有两种:Tcp和Http。在.Net中,System.Runtime.Remoting.Channel中界说了IChannel接口。IChannel接口包含了TcpChannel通道范例和Http通道范例。它们分离对应Remoting通道的这两品种型。
TcpChannel范例放在名字空间System.Runtime.Remoting.Channel.Tcp中。Tcp通道供应了基于Socket的传输工具,利用Tcp协定来超过Remoting界限传输序列化的动静流。TcpChannel范例默许利用二进制格局序列化动静工具,因而它具有更高的传输功能。HttpChannel范例放在名字空间System.Runtime.Remoting.Channel.Http中。它供应了一种利用Http协定,使其能在Internet上穿越防火墙传输序列化动静流。默许情形下,HttpChannel范例利用Soap格局序列化动静工具,因而它具有更好的互操纵性。一般在局域网内,我们更多地利用TcpChannel;假如要穿越防火墙,则利用HttpChannel。
2、远程工具的激活体例
在会见远程范例的一个工具实例之前,必需经由过程一个名为Activation的历程创立它并举行初始化。这类客户端经由过程通道来创立远程工具,称为工具的激活。在Remoting中,远程工具的激活分为两年夜类:服务器端激活和客户端激活。
(1)服务器端激活,又叫做WellKnow体例,良多又翻译为出名工具。为何称为出名工具激活形式呢?是由于服务器使用程序在激活工具实例之前会在一个尽人皆知的一致资本标识符(URI)下去公布这个范例。然后该服务器历程会为此范例设置一个WellKnown工具,并依据指定的端口或地点来公布工具。.NetRemoting把服务器端激活又分为SingleTon形式和SingleCall形式两种。
SingleTon形式:此为有形态形式。假如设置为SingleTon激活体例,则Remoting将为一切客户端创建统一个工具实例。当工具处于举动形态时,SingleTon实例会处置一切厥后的客户端会见哀求,而不论它们是统一个客户端,仍是其他客户端。SingleTon实例将在办法挪用中一向保持其形态。举例来讲,假如一个远程工具有一个累加办法(i=0;++i),被多个客户端(比方两个)挪用。假如设置为SingleTon体例,则第一个客户取得值为1,第二个客户取得值为2,由于他们取得的工具实例是不异的。假如熟习Asp.Net的形态办理,我们能够以为它是一种Application形态。
SingleCall形式:SingleCall是一种无形态形式。一旦设置为SingleCall形式,则当客户端挪用远程工具的办法时,Remoting会为每个客户端创建一个远程工具实例,至于工具实例的烧毁则是由GC主动办理的。同上一个例子而言,则会见远程工具的两个客户取得的都是1。我们仍旧能够自创Asp.Net的形态办理,以为它是一种Session形态。
(2)客户端激活。与WellKnown形式分歧,Remoting在激活每一个工具实例的时分,会给每一个客户端激活的范例指派一个URI。客户端激活形式一旦取得客户真个哀求,将为每个客户端都创建一个实例援用。SingleCall形式和客户端激活形式是有区分的:起首,工具实例创立的工夫纷歧样。客户端激活体例是客户一旦收回挪用的哀求,就实例化;而SingleCall则是要比及挪用工具办法时再创立。其次,SingleCall形式激活的工具是无形态的,工具性命期的办理是由GC办理的,而客户端激活的工具则有形态,其性命周期可自界说。其三,两种激活形式在服务器端和客户端完成的办法纷歧样。特别是在客户端,SingleCall形式是由GetObject()来激活,它挪用工具默许的机关函数。而客户端激活形式,则经由过程CreateInstance()来激活,它能够传送参数,以是能够挪用自界说的机关函数来创立实例。
<P> 2、远程工具的界说
后面讲到,客户端在猎取服务器端工具时,并非取得实践的服务端工具,而是取得它的援用。因而在Remoting中,关于远程工具有一些必需的界说标准要遵守。
因为Remoting传送的工具是以援用的体例,因而所传送的远程工具类必需承继MarshalByRefObject。MSDN对MarshalByRefObject的申明是:MarshalByRefObject是那些经由过程利用代办署理互换动静来超过使用程序域界限举行通讯的工具的基类。不是从MarshalByRefObject承继的工具会以隐式体例按值封送。当远程使用程序援用一个按值封送的工具时,将超过远程处置界限传送该工具的正本。由于您但愿利用代办署理办法而不是正本办法举行通讯,因而必要承继MarshallByRefObject。
以下是一个远程工具类的界说:
publicclassServerObject:MarshalByRefObject
{
publicPersonGetPersonInfo(stringname,stringsex,intage)
{
Personperson=newPerson();
person.Name=name;
person.Sex=sex;
person.Age=age;
returnperson;
}
}
这个类只完成了最复杂的办法,就是设置一团体的基础信息,并前往一个Person类工具。注重这里前往的Person类。因为这里所传送的Person则是以传值的体例来完成的,而Remoting请求必需是援用的工具,以是必需将Person类序列化。
因而,在Remoting中的远程工具中,假如还要挪用或传送某个工具,比方类,大概布局,则该类或布局则必需完成串行化Attribute[SerializableAttribute]:
[Serializable]
publicclassPerson
{
publicPerson()
{}
privatestringname;
privatestringsex;
privateintage;
publicstringName
{
get{returnname;}
set{name=value;}
}
publicstringSex
{
get{returnsex;}
set{sex=value;}
}
publicintAge
{
get{returnage;}
set{age=value;}
}
}
将该远程工具以类库的体例编译成Dll。这个Dll将分离放在服务器端和客户端,以增加援用。
在Remoting中可以传送的远程工具能够是各类范例,包含庞大的DataSet工具,只需它可以被序列化。远程工具也能够包括事务,但服务器端关于事务的处置对照特别,我将在本系列之三中先容。
<P> 3、服务器端
依据第一部分所述,依据激活形式的分歧,通道范例的分歧服务器真个完成体例也有所分歧。大致上说,服务器端应分为三步:
1、注册通道
要超过使用程序域举行通讯,必需完成通道。如前所述,Remoting供应了IChannel接口,分离包括TcpChannel和HttpChannel两品种型的通道。这两品种型除功能和序列化数据的格局分歧外,完成的体例完整分歧,因而上面我们就以TcpChannel为例。
注册TcpChannel,起首要在项目中增加援用“System.Runtime.Remoting”,然后using名字空间:System.Runtime.Remoting.Channel.Tcp。代码以下:
TcpChannelchannel=newTcpChannel(8080);
ChannelServices.RegisterChannel(channel);
在实例化通道工具时,将端标语作为参数传送。然后再挪用静态办法RegisterChannel()来注册该通道工具便可。
2、注册远程工具
注册了通道后,要能激活远程工具,必需在通道中注册该工具。依据激活形式的分歧,注册工具的办法也分歧。
(1)SingleTon形式
关于WellKnown工具,能够经由过程静态办法RemotingConfiguration.RegisterWellKnownServiceType()来完成:
RemotingConfiguration.RegisterWellKnownServiceType(typeof(ServerRemoteObject.ServerObject),
"ServiceMessage",WellKnownObjectMode.SingleTon);
(2)SingleCall形式
注册工具的办法基础上和SingleTon形式不异,只必要将列举参数WellKnownObjectMode改成SingleCall就能够了。
RemotingConfiguration.RegisterWellKnownServiceType(typeof(ServerRemoteObject.ServerObject),
"ServiceMessage",WellKnownObjectMode.SingleCall);
(3)客户端激活形式
关于客户端激活形式,利用的办法又有分歧,但区分不年夜,看了代码就一览无余。
RemotingConfiguration.ApplicationName="ServiceMessage";
RemotingConfiguration.RegisterActivatedServiceType(typeof(ServerRemoteObject.ServerObject));
为何要在注册工具办法前设置ApplicationName属性呢?实在这个属性就是该工具的URI。关于WellKnown形式,URI是放在RegisterWellKnownServiceType()办法的参数中,固然也能够拿出来专门对ApplicationName属性赋值。而RegisterActivatedServiceType()办法的重载中,没有ApplicationName的参数,以是必需分隔。
3、刊出通道
假如要封闭Remoting的服务,则必要刊出通道,也能够封闭对通道的监听。在Remoting中当我们注册通道的时分,就主动开启了通道的监听。而假如封闭了对通道的监听,则该通道就没法承受客户真个哀求,但通道仍旧存在,假如你想再一次注册该通道,会抛出非常。
//取得以后已注册的通道;
IChannel[]channels=ChannelServices.RegisteredChannels;
//封闭指命名为MyTcp的通道;
foreach(IChanneleachChannelinchannels)
{
if(eachChannel.ChannelName=="MyTcp")
{
TcpChanneltcpChannel=(TcpChannel)eachChannel;
//封闭监听;
tcpChannel.StopListening(null);
//刊出通道;
ChannelServices.UnregisterChannel(tcpChannel);
}
}
代码中,RegisterdChannel属性取得的是以后已注册的通道。在Remoting中,是同意同时注册多个通道的,这一点会在前面申明。
<P> 4、客户端
客户端次要做两件事,一是注册通道。这一点从图一就能够看出,Remoting中服务器端和客户端都必需经由过程通道来传送动静,以取得远程工具。第二步则是取得该远程工具。
1、注册通道:
TcpChannelchannel=newTcpChannel();
ChannelServices.RegisterChannel(channel);
注重在客户端实例化通道时,是挪用的默许机关函数,即没有传送端标语。现实上,这个端标语是缺一不成的,只不外它的指定被放在前面作为了Uri的一部分。
2、取得远程工具。
与服务器端不异,分歧的激活形式决意了客户真个完成体例也将分歧。不外这个区分仅仅是WellKnown激活形式和客户端激活形式之间的区分,而关于SingleTon和SingleCall形式,客户真个完成完整不异。
(1)WellKnown激活形式
要取得服务器真个出名远程工具,可经由过程Activator历程的GetObject()办法来取得:
ServerRemoteObject.ServerObjectserverObj=(ServerRemoteObject.ServerObject)Activator.GetObject(
typeof(ServerRemoteObject.ServerObject),"tcp://localhost:8080/ServiceMessage");
起首以WellKnown形式激活,客户端取得工具的办法是利用GetObject()。个中参数第一个是远程工具的范例。第二个参数就是服务器真个uri。假如是http通道,天然是用http://localhost:8080/ServiceMessage了。由于我是用当地机,以是这里是localhost,你能够器具体的服务器IP地点来取代它。端口必需和服务器真个端口分歧。前面则是服务器界说的远程工具服务名,即ApplicationName属性的内容。
(2)客户端激活形式
如前所述,WellKnown形式在客户端创立工具时,只能挪用默许的机关函数,下面的代码就申明了这一点,由于GetObject()办法不克不及传送机关函数的参数。而客户端激活形式则能够经由过程自界说的机关函数来创立远程工具。
客户端激活形式有两种办法:
1)挪用RemotingConfiguration的静态办法RegisterActivatedClientType()。这个办法前往值为Void,它只是将远程工具注册在客户端罢了。详细的实例化还必要挪用工具类的机关函数。
RemotingConfiguration.RegisterActivatedClientType(typeof(ServerRemoteObject.ServerObject),
"tcp://localhost:8080/ServiceMessage");
ServerRemoteObject.ServerObjectserverObj=newServerRemoteObject.ServerObject();
2)挪用历程Activator的CreateInstance()办法。这个办法将创立办法参数指定范例的类工具。它与后面的GetObject()分歧的是,它要在客户端挪用机关函数,而GetObject()只是取得工具,而创立实例是在服务器端完成的。CreateInstance()办法有良多个重载,我侧重说一下个中经常使用的两个。
a、publicstaticobjectCreateInstance(Typetype,object[]args,object[]activationAttributes);
参数申明:
type:要创立的工具的范例。
args:与要挪用机关函数的参数数目、按次和范例婚配的参数数组。假如args为空数组或空援用(VisualBasic中为Nothing),则挪用不带任何参数的机关函数(默许机关函数)。
activationAttributes:包括一个或多个能够介入激活的属性的数组。
这里的参数args是一个object[]数组范例。它能够传送要创立工具的机关函数中的参数。从这里实在能够失掉一个结论:WellKnown激活形式所传送的远程工具类,只能利用默许的机关函数;而Activated形式则能够用户自界说机关函数。activationAttributes参数在这个办法中一般用来传送服务器的url。
假定我们的远程工具类ServerObject有个机关函数:
ServerObject(stringpName,stringpSex,intpAge)
{
name=pName;
sex=pSex;
age=pAge;
}
那末完成的代码是:
object[]attrs={newUrlAttribute("tcp://localhost:8080/ServiceMessage")};
object[]objs=newobject[3];
objs[0]="wayfarer";
objs[1]="male";
objs[2]=28;
ServerRemoteObject.ServerObject=Activator.CreateInstance(
typeof(ServerRemoteObject.ServerObject),objs,attrs);
能够看到,objs[]数组传送的就是机关函数的参数。
b、publicstaticObjectHandleCreateInstance(stringassemblyName,stringtypeName,object[]activationAttribute);
参数申明:
assemblyName:将在个中查找名为typeName的范例的程序集的称号。假如assemblyName为空援用(VisualBasic中为Nothing),则搜刮正在实行的程序集。
typeName:首选范例的称号。
activationAttributes:包括一个或多个能够介入激活的属性的数组。
参数申明一览无余。注重这个办法前往值为ObjectHandle范例,因而代码与前分歧:
object[]attrs={newUrlAttribute("tcp://localhost:8080/EchoMessage")};
ObjectHandlehandle=Activator.CreateInstance("ServerRemoteObject",
"ServerRemoteObject.ServerObject",attrs);
ServerRemoteObject.ServerObjectobj=(ServerRemoteObject.ServerObject)handle.Unwrap();
这个办法实践上是挪用的默许机关函数。ObjectHandle.Unwrap()办法是前往被包装的工具。
申明:要利用UrlAttribute,还必要在定名空间中增加:usingSystem.Runtime.Remoting.Activation;
<P> 5、Remoting基本的增补
经由过程下面的形貌,基础上已完成了一个最复杂的Remoting程序。这是一个尺度的创立Remoting程序的办法,但在实践开辟过程当中,我们碰到的情形大概光怪陆离,假如只把握一种所谓的“尺度”,就妄图能够“一招鲜、吃遍天”,是不成能的。
1、注册多个通道
在Remoting中,同意同时创立多个通道,即依据分歧的端口创立分歧的通道。可是,Remoting请求通道的名字必需分歧,由于它要用来作为通道的独一标识符。固然IChannel有ChannelName属性,但这个属性是只读的。因而后面所述的创立通道的办法没法完成同时注册多个通道的请求。
这个时分,我们必需用到System.Collection中的IDictionary接口:
注册Tcp通道:
IDictionarytcpProp=newHashtable();
tcpProp["name"]="tcp9090";
tcpProp["port"]=9090;
IChannelchannel=newTcpChannel(tcpProp,
newBinaryClientFormatterSinkProvider(),
newBinaryServerFormatterSinkProvider());
ChannelServices.RegisterChannel(channel);
注册Http通道:
IDictionaryhttpProp=newHashtable();
httpProp["name"]="http8080";
httpProp["port"]=8080;
IChannelchannel=newHttpChannel(httpProp,
newSoapClientFormatterSinkProvider(),
newSoapServerFormatterSinkProvider());
ChannelServices.RegisterChannel(channel);
在name属性中,界说分歧的通道称号就能够了。
2、远程工具元数据相干性
因为服务器端和客户端都要用到远程工具,一般的体例是天生两份完整不异的工具Dll,分离增加援用。不外为了代码的平安性,且下降客户端对远程工具元数据的相干性,我们有需要对这类体例举行修改。即在服务器端完成远程工具,而在客户端则删除这些完成的元数据。
因为激活形式的分歧,在客户端创立工具的办法也分歧,以是要分别元数据的相干性,也应分为两种情形。
(1)WellKnown激活形式:
经由过程接口来完成。在服务器端,供应接口和详细类的完成,而在客户端仅供应接口:
publicinterfaceIServerObject
{
PersonGetPersonInfo(stringname,stringsex,intage);
}
publicclassServerObject:MarshalByRefObject,IServerObject
{......}
注重:双方天生该工具程序集的名字必需不异,严厉地说,是定名空间的名字必需不异。
(2)客户端激活形式:
如前所述,关于客户端激活形式,不论是利用静态办法,仍是利用CreateInstance()办法,都必需在客户端挪用机关函数实例化工具。以是,在客户端我们供应的远程工具,就不克不及只供应接口,而没有类的完成。实践上,要做到与远程工具元数据的分别,能够由两种办法供选择:
a、使用WellKnown激活形式摹拟客户端激活形式:
办法是使用计划形式中的“笼统工场”,上面的类图表形貌了整体办理计划:
<P>
我们在服务器真个远程工具中加上笼统工场的接口和完成类:
publicinterfaceIServerObject
{
PersonGetPersonInfo(stringname,stringsex,intage);
}
publicinterfaceIServerObjFactory
{
IServerObjectCreateInstance();
}
publicclassServerObject:MarshalByRefObject,IServerObject
{
publicPersonGetPersonInfo(stringname,stringsex,intage)
{
Personperson=newPerson();
person.Name=name;
person.Sex=sex;
person.Age=age;
returnperson;
}
}
publicclassServerObjFactory:MarshalByRefObject,IServerObjFactory
{
publicIServerObjectCreateInstance()
{
returnnewServerObject();
}
}
然后再客户真个远程工具中只供应工场接口和本来的工具接口:
publicinterfaceIServerObject
{
PersonGetPersonInfo(stringname,stringsex,intage);
}
publicinterfaceIServerObjFactory
{
IServerObjectCreateInstance();
}
我们用WellKnown激活形式注册远程工具,在服务器端:
//传送工具;
RemotingConfiguration.RegisterWellKnownServiceType(
typeof(ServerRemoteObject.ServerObjFactory),
"ServiceMessage",WellKnownObjectMode.SingleCall);
注重这里注册的不是ServerObject类工具,而是ServerObjFactory类工具。
客户端:
ServerRemoteObject.IServerObjFactoryserverFactory=
(ServerRemoteObject.IServerObjFactory)Activator.GetObject(
typeof(ServerRemoteObject.IServerObjFactory),
"tcp://localhost:8080/ServiceMessage");
ServerRemoteObject.IServerObjectserverObj=serverFactory.CreateInstance();
为何说这是一种客户端激活形式的摹拟呢?从激活的办法来看,我们是利用了SingleCall形式来激活工具,但此时激活的并不是我们要传送的远程工具,而是工场工具。假如客户端要创立远程工具,还应当经由过程工场工具的CreateInstance()办法来取得。而这个办法恰是在客户端挪用的。因而它的完成体例就同等于客户端激活形式。
b、使用替换类来代替远程工具的元数据
实践上,我们能够用一个trick,来棍骗Remoting。这里所说的替换类就是这个trick了。既然是供应服务,Remoting传送的远程工具实在现的细节固然是放在服务器端。而要在客户端放工具的正本,不外是由于客户端必需挪用机关函数,而接纳的无法之举。既然详细的完成是在服务器端,又为了能在客户端实例化,那末在客户端就完成这些好了。至于完成的细节,就不必管了。
假如远程工具无方法,服务器端则供应办法完成,而客户端就供应这个办法就OK了,至于内里的完成,你能够是抛出一个非常,大概return一个null值;假如办法前往void,那末内里能够是空。关头是这个客户端类工具要有这个办法。这个办法的完成,实在和办法的声明差未几,以是我说是一个trick。办法如是,机关函数也云云。
仍是用代码来讲明这类“诡计”,更直不雅:
服务器端:
publicclassServerObject:MarshalByRefObject
{
publicServerObject()
{}
publicPersonGetPersonInfo(stringname,stringsex,intage)
{
Personperson=newPerson();
person.Name=name;
person.Sex=sex;
person.Age=age;
returnperson;
}
}
客户端:
publicclassServerObject:MarshalByRefObject
{
publicServerObj()
{
thrownewSystem.NotImplementedException();
}
publicPersonGetPersonInfo(stringname,stringsex,intage)
{
thrownewSystem.NotImplementedException();
}
}
对照客户端和服务器端,客户真个办法GetPersonInfo(),没有详细的完成细节,只是抛出了一个非常。大概间接写上语句returnnull,还是OK。我们称客户真个这个类为远程工具的替换类。
<P> 3、使用设置文件完成
后面所述的办法,于服务器uri、端口、和激活形式的设置是用代码来完成的。实在我们也能够用设置文件来设置。如许做有个优点,由于这个设置文件是Xml文档。假如必要改动端口或其他,我们就不必要修正程序,偏重新编译,而是只必要改动这个设置文件便可。(1)服务器真个设置文件:
<configuration>
<system.runtime.remoting>
<applicationname="ServerRemoting">
<service>
<wellknownmode="Singleton"type="ServerRemoteObject.ServerObject"objectUri="ServiceMessage"/>
</service>
<channels>
<channelref="tcp"port="8080"/>
</channels>
</application>
</system.runtime.remoting>
</configuration>
假如是客户端激活形式,则把wellknown改成activated,同时删除mode属性。
把该设置文件放到服务器程序的使用程叙文件夹中,定名为ServerRemoting.config。那末后面的服务器端程序间接用这条语句便可:
RemotingConfiguration.Configure("ServerRemoting.config");
(2)客户端设置文件
假如是客户端激活形式,修正和下面一样。挪用也是利用RemotingConfiguration.Configure()办法来挪用存储在客户真个设置文件。
设置文件还能够放在machine.config中。假如客户端程序是web使用程序,则能够放在web.config中。
4、启动/封闭指定远程工具
Remoting中没有供应相似UnregisterWellKnownServiceType()的办法,也便是说,一旦经由过程注册了远程工具,假如没有封闭通道的话,该工具就一向存在于通道中。只需客户端激该死工具,就会创立工具实例。假如Remoting传送的只要一个远程工具,这不存在成绩,封闭通道就能够了。假如传送多个远程工具呢?要封闭指定的远程工具应当怎样做?封闭以后又必要启动又该怎样?
我们注重到在Remoting中供应了Marshal()和Disconnect()办法,谜底就在这里。Marshal()办法是将MarshalByRefObject类工具转化为ObjRef类工具,这个工具是存储天生代办署理以与远程工具通信所需的一切相干信息。如许就能够将该实例序列化以便在使用程序域之间和经由过程收集举行传输,客户端就能够挪用了。而Disconnect()办法则将详细的实例工具从通道中止开。
办法以下:
起首注册通道:
TcpChannelchannel=newTcpChannel(8080);
ChannelServices.RegisterChannel(channel);
接着启动服务:
先在服务器端实例化远程工具。
ServerObjectobj=newServerObject();
然后,注册该工具。注重这里不必RemotingConfiguration.RegisterWellKnownServiceType(),而是利用RemotingServices.Marshal():
ObjRefobjrefWellKnown=RemotingServices.Marshal(obj,"ServiceMessage");
假如要刊出工具,则:
RemotingServices.Disconnect(obj);
要注重,这里Disconnect的类工具必需是后面实例化的工具。正由于此,我们能够依据必要创立指定的远程工具,而封闭时,则Disconnect之前实例化的工具。
至于客户真个挪用,和后面WellKnown形式的办法不异,仍旧是经由过程Activator.GetObject()来取得。但从完成代码来看,我们会注重到一个成绩,因为服务器端是显式的实例化了远程工具,因而不论客户端有几,是不是不异,它们挪用的都是统一个远程工具。因而我们将这个办法称为摹拟的SingleTon形式。
客户端激活形式
我们也能够经由过程Marshal()和Disconnect()来摹拟客户端激活形式。起首我们往返顾“远程工具元数据相干性”一节,在这一节中,我说到接纳计划形式的“笼统工场”来创立工具实例,以此用SingleCall形式来摹拟客户端激活形式。在细心想一想后面的摹拟的SingleTon形式。是否是谜底就将呼之欲出呢?
在“摹拟的SingleTon”形式中,我们是将详细的远程工具实例举行Marshal,以此让客户端取得该工具的援用信息。那末我们换一种思绪,当我们用笼统工场供应接口,工场类完成创立远程工具的办法。然后我们在服务器端创立工场类实例。再将这个工场类实例举行Marshal。而客户端猎取工具时,不是猎取详细的远程工具,而是猎取详细的工场类工具。然后再挪用CreateInstance()办法来创立详细的远程工具实例。此时,关于多个客户端而言,挪用的是统一个工场类工具;但是远程工具是在各个客户端本人创立的,因而关于远程工具而言,则是由客户端激活,创立的是分歧工具了。
当我们要启动/封闭指定工具时,只必要用Disconnet()办法来刊出工场类工具就能够了。
6、小结
Microsoft.NetRemoting真能够说是胸无点墨。全部Remoting的内容不是我这一篇小文所能尽述的,更不是我这个Remoting的初学者所能把握的。王国维在《人世词话》一书中写到:古今之成年夜奇迹年夜学问者,必经由三种地步。“昨夜西风凋碧树,独上高楼,看尽天边路。”此第一地步也。“衣带渐宽终不悔,为伊消得人干瘪。”此第二地步也。“众里寻他千百度,蓦地回想,那人却在灯火衰退处。”此第三地步也。如以此来描述我对Remoting的进修,还处于“独上高楼,看尽天边路”的时分,真能够说还不曾登堂进室。
也许需得“衣带渐宽”,学得Remoting“终不悔”,刚刚能够“蓦地回想”吧。你觉得数据库怎么样? |
|