Remoting有三个部分组成,远程对象(一般为类库)、服务器和客户端。服务器和客户端都必须
引用远程对 象DLL,已经固定System.Runtime.Remoting的DLL。服务器和客户端必须都开启.
远程对象: 指被客户端调用的类(类中包括在客户端实现的方法)。
该类有特殊要求,它必须属于以下三种中的一种:
1. 按值排列的类,串行化通过通道,没有远程标识,不是透明代理,是真实代理,而
且必须实现 ISerializable或属性[Serializable] 。
透明代理:执行远程对象的所有公共方法,在执行时代用RealProxy和Invoke()方法。
在客户端通过以下代码进行验证:用类RemotingServices,命名空间System.Runtime.Remoting;
if(RemotingServices.IsTransparentProxy(serialize))
{
Console.WriteLine(" 不是透明代理,是真实代理"
}该类代码如下:
[Serializable]
public class mySerialized
{
public void Food()
{
Console.WriteLine("mySerialized.Food is called");
}
}
2. 按引用排列的类,有远程标识,有代理对象,是透明代理必须继承System.MarshalByRefObject类
public class Hello:System.MarshalByRefObject
{
public void Food()
{
Console.WriteLine("myRemote.Food is called");
}
}服务器: 启着实现远程对象代理的作用。首先它必须定义一个通道,为Http还是Tcp协议的通道,
接着把通道注册到Remoting中, 最后服务器注册远程对象类型,并指定客使用的URL和模式。
1. 创建通道有类TcpServerChannel和HttpServerChannel,可以开通多通道,在实例该类时,
必须指定其端口号。或者也可以自己对该通道的详细说明,这样得要指定通道的传输
方式,是二进制符(较快)还是以SOAP符。
如下:
使用直接实例化
TcpServerChannel channel=new TcpServerChannel(8086); 或是Http
HttpServerChannel channel=new HttpServerChannel(8087);
或者添加相应属性:命名空间System.Collections.Specialized下ListDictionary
//通道使用的是SOAP标识符,也可以使用二进制
property.Add("Name","TCP channel with soap a formatter");
property.Add("Prority",5); //优先级为5
property.Add("port",8086); //端口为8086
//把要传递的数据用SOAP格式符进行,也可以用二进制,类为BinaryServerFormatterSinkProvider
SoapServerFormatterSinkProvider soapProvid=new SoapServerFormatterSinkProvider();
//把这种属性应用到通道中,其Http也是一样的TcpServerChannel tChannel=new TcpServerChannel(property,soapProvider);

如果要查看通道的属性的话:(
protected static void showChannelProperty(IChannelReceiver channel)
{
Console.WriteLine("Name :"+channel.ChannelName);
Console.WriteLine("Priority :"+channel.ChannelPriority);//优先级
//如果是HTTP协议
if(channel is HttpChannel)
{
HttpChannel hChannel=channel as HttpChannel;
//监听类型
Console.WriteLine("Scheme :"+hChannel.ChannelScheme);
}
//存储远程通道数据,获取通道数据
ChannelDataStore data=(ChannelDataStore)channel.ChannelData;
foreach(string uri in data.ChannelUris)
{
Console.WriteLine(" Url :"+uri);
}
} 2. 注册已经定义好的通道到Remoting中。
ChannelServices.RegisterChannel(channel);
3. 激活(注册)远程对象类型,使用类RemotingConfiguration
RemotingConfiguration.RegisterWellKnownServiceType
(typeof(Hello), //类型,远程对象的类
"Hi", //URL
WellKnownObjectMode.SingleCall); //MODE模式客户端: 先注册一通道,接着激活远程对象的代理对象(这和服务器注册的对象的有关的
使用其 准确的URL和端口号),最后就可以用产生的代理类进行调用远程的方法
ChannelServices.RegisterChannel(new TcpClientChannel());
//创建代理类,并使用Activator进行激活,产生一个代理对象
Hello obj=(Hello)Activator.GetObject
(typeof(Hello), //远程对象类类
"tcp://localhost:8086/Hi");
//协议,服务器名(或IP)、URL、端口,URL也就是服务器上写明的
//格式为 protocol://server:port/url或者:使用RemotingConfiguration类来进行激活,但不返回对象
RemotingConfiguration.RegisterWellKnownClientType
(typeof(Hello), //类型,远程对象的类
"Hi", //URL
WellKnownObjectMode.SingleCall); //MODE模
Hello obj=new Hello(); //实例 使用Activator类下方法GetOjbect()在对象方法完成之后就小毁了, 而Activator下方法
CreateInstance()可以指定使用时间,也就是租借时间.这样必须引用类
System.Runtime.Remoting.Activation.UrlAttribute
bject[] arlat={newUrlAttribute("tcp://localhost:8086/Hi")};
ojectHandle handle=Activator.CreateInstance
("RemotingHello",//程序集的名称,也就是DLL
"RemotingHello.Hello", //创建名称指定的类型事例也就是引用的类
urlat);
Hello obj=(Hello)handle.Unwrap();//返回被包装的对象 修改租借时间,重写远程对象的MarshalByRefObject类下方法InitializeLifetimeService()
//重新写租借的默认时间情况
public override object InitializeLifetimeService()
{
ILease lease=(ILease)base.InitializeLifetimeService();
//租借10分
lease.InitialLeaseTime=TimeSpan.FromMinutes(10);
lease.RenewOnCallTime=TimeSpan.FromSeconds(40);
return lease;
}

浙公网安备 33010602011771号