Net Remoting基础篇5
点击次数:20 次 发布日期:2008-11-26 10:43:51 作者:源代码网
|
源代码网推荐 源代码网推荐 实际上,我们可以用一个trick,来欺骗Remoting。这里所说的替代类就是这个trick了。既然是提供服务,Remoting传递的远程对象其实现的细节当然是放在服务器端。而要在客户端放对象的副本,不过是因为客户端必须调用构造函数,而采取的无奈之举。既然具体的实现是在服务器端,又为了能在客户端实例化,那么在客户端就实现这些好了。至于实现的细节,就不用管了。 源代码网推荐 源代码网推荐 如果远程对象有方法,服务器端则提供方法实现,而客户端就提供这个方法就OK了,至于里面的实现,你可以是抛出一个异常,或者return 一个null值;如果方法返回void,那么里面可以是空。关键是这个客户端类对象要有这个方法。这个方法的实现,其实和方法的声明差不多,所以我说是一个trick。方法如是,构造函数也如此。 源代码网推荐 源代码网推荐 还是用代码来说明这种“阴谋”,更直观: 源代码网推荐 源代码网推荐 服务器端: 源代码网推荐 public class ServerObject:MarshalByRefObject 源代码网推荐 { 源代码网推荐 public ServerObject() 源代码网推荐 { 源代码网推荐 源代码网推荐 } 源代码网推荐 源代码网推荐 public Person GetPersonInfo(string name,string sex,int age) 源代码网推荐 { 源代码网推荐 Person person = new Person(); 源代码网推荐 person.Name = name; 源代码网推荐 person.Sex = sex; 源代码网推荐 person.Age = age; 源代码网推荐 return person; 源代码网推荐 } 源代码网推荐 } 源代码网推荐 源代码网推荐 客户端: 源代码网推荐 public class ServerObject:MarshalByRefObject 源代码网推荐 { 源代码网推荐 public ServerObj() 源代码网推荐 { 源代码网推荐 throw new System.NotImplementedException(); 源代码网推荐 } 源代码网推荐 源代码网推荐 public Person GetPersonInfo(string name,string sex,int age) 源代码网推荐 { 源代码网推荐 throw new System.NotImplementedException(); 源代码网推荐 } 源代码网推荐 } 源代码网推荐 源代码网推荐 比较客户端和服务器端,客户端的方法GetPersonInfo(),没有具体的实现细节,只是抛出了一个异常。或者直接写上语句return null,照样OK。我们称客户端的这个类为远程对象的替代类。 源代码网推荐 源代码网推荐 3、利用配置文件实现 源代码网推荐 源代码网推荐 前面所述的方法,于服务器uri、端口、以及激活模式的设置是用代码来完成的。其实我们也可以用配置文件来设置。这样做有个好处,因为这个配置文件是XML文档。如果需要改变端口或其他,我们就不需要修改程序,并重新编译,而是只需要改变这个配置文件即可。 源代码网推荐 源代码网推荐 (1) 服务器端的配置文件: 源代码网推荐 <configuration> 源代码网推荐 <system.runtime.remoting> 源代码网推荐 <application name="ServerRemoting"> 源代码网推荐 <service> 源代码网推荐 <wellknown mode="Singleton" type="ServerRemoteObject.ServerObject" objectUri="ServiceMessage"/> 源代码网推荐 </service> 源代码网推荐 <channels> 源代码网推荐 <channel ref="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()方法则将具体的实例对象从通道中断开。 源代码网推荐 源代码网推荐 方法如下: 源代码网推荐 首先注册通道: 源代码网推荐 TcpChannel channel = new TcpChannel(8080); 源代码网推荐 ChannelServices.RegisterChannel(channel); 源代码网推荐 源代码网推荐 接着启动服务: 源代码网推荐 先在服务器端实例化远程对象。 源代码网推荐 ServerObject obj = new ServerObject(); 源代码网推荐 源代码网推荐 然后,注册该对象。注意这里不用RemotingConfiguration.RegisterWellKnownServiceType(),而是使用RemotingServices.Marshal(): 源代码网推荐 源代码网推荐 ObjRef objrefWellKnown = RemotingServices.Marshal(obj, "ServiceMessage"); 源代码网推荐 源代码网推荐 如果要注销对象,则: 源代码网推荐 RemotingServices.Disconnect(obj); 源代码网推荐 源代码网推荐 要注意,这里Disconnect的类对象必须是前面实例化的对象。正因为此,我们可以根据需要创建指定的远程对象,而关闭时,则Disconnect之前实例化的对象。 源代码网推荐 源代码网推荐 至于客户端的调用,和前面WellKnown模式的方法相同,仍然是通过Activator.GetObject()来获得。但从实现代码来看,我们会注意到一个问题,由于服务器端是显式的实例化了远程对象,因此不管客户端有多少,是否相同,它们调用的都是同一个远程对象。因此我们将这个方法称为模拟的SingleTon模式。 源代码网推荐 源代码网推荐 客户端激活模式 源代码网推荐 源代码网推荐 做人要厚道,请注明转自酷网动力(www.ASPCOOL.COM)。 源代码网推荐 源代码网供稿. |
