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(); |