一、服务器端激活模式
1、SingleCall模式
故名思义,SingleCall模式是一种单独调用激活模式,也就是说服务器端监听到客户端的代理类来了一个函数调用的时候,它都会自动在服务器端创建一个远程对象的实例(Remoting Instance)。然后等客户端完成了这个函数调用的时候,服务器端就会自动把这个远程对象的实例垃圾回收。也就是说它的生命周期只是局限在函数调用内部。
SingleCall模式它适合于无状态的服务(stateless applications),而且远程对象创建起来比较容易的情况。这和Web Service类似。通过代理类Get一个Property,和Set一个Property ,可能是在不同的对象里面实行的,也就是说Get可能在某个对象里面实行,Set却在另外一个对象里面实行的。 那么代理类先调用了Set以后紧接着去调用Get,得到的值可能就不是刚才Set的那个值了。所以说SingleCall得到的是一种无状态的应用程序。
SingleCall模式的负载平衡性能(load-balanced)比较好。
2、Singleton模式
Singleton模式和SingleCall模式正好向反,也就是不管你客户端有多少个代理类,有多少个函数调用,服务器端只创建一个远程服务对象实例供客户端调用。
Singleton模式的远程对象实例的创建是在他被客户端的一次调用以后创建的,它的生命周期将会被一直保存下去,直到这个宿主应用程序最后被关闭掉它才会随着宿主应用程序一起被垃圾回收。
它比较特别的一点就是在宿主应用程序的生命周期内,只有一个远程对象实例在提供服务!
也正因为它只有一个远程对象实例所以你可以在这个对象中保存一些状态信息,比如张三来了保存了一个信息,那么李四来了再读取的时候读到的就是先前张三创建的那个数值
Singleton模式它适合于对象的构造过程比较耗时。举个简单的例子,比如股票查询的一个服务,创建一个股票远程实例对象需要5分钟的时间,可是查询一个股票价格之需要花几秒钟就可以完成。这种情况下并不是每个请求都要构造一个远程对象,这就比较适合用Singleton模式。
如果把一个远程对象宿主服务器把它配置成为Singlecall或者Singleton模式也就是说是服务器段激活模式的话,我们就称这个远程对象为众所周知的(WellKnow)的对象,为什么呢?因为如果一个对象是服务器段激活模式的话,那么这个对象就把它的信息都暴露给了远程调用者:
服务类型、服务名称、生命周期等。这样服务器已经把什么都告诉远程调用者了,所以说我是一个众所周知的远程对象(WellKnow Object)。
比如服务器端完成了下面的信息提供:
ChannelServices.RegisterChannel(new TcpChannel(7711));
RemotingConfiguration.ApplicationName="TranserRemotingService";
//如果这个宿主程序是注册在IIS上的话,那么这个ApplicationName就相当于IIS上的虚拟目录
WellKnownServiceTypeEntry WKSTE = new WellKnownServiceTypeEntry(typeof(TransferMoney),"URLAssemblyComponent",WellKnownObjectMode.Singlecall);
RemotingConfiguration.RegisterWellKnownServiceType(WKSTE);
这时候客户端什么都知道了当然可以众所周知地进行调用这个服务上的函数
if(rbtHttp.Checked==true)//Http信道
{
ITransfer ProxyObj=(ITransfer) Activator.GetObject(typeof(ITransfer),"http://"+tbHostServer.Text+":7608/TranserRemotingService/URLAssemblyComponent");
double atemp=Convert.ToDouble(tBMoney.Text);
msg=ProxyObj.getTransferResult(Convert.ToDouble(atemp));
}
else//Tcp信道
{
ITransfer ProxyObj=(ITransfer) Activator.GetObject(typeof(ITransfer),"tcp://"+tbHostServer.Text+":7711/TranserRemotingService/URLAssemblyComponent");
double atemp=Convert.ToDouble(tBMoney.Text);
msg=ProxyObj.getTransferResult(Convert.ToDouble(atemp));
}
其中客户端就是根据服务器IP及端口+服务应用名称(类似于IIS的虚拟目录)+应用名称就可以找到宿主服务器所提供的这个函数getTransferResult了。
所以说用WellKnow这个词来描述非常贴切。
这里想提一下Activator.GetObject ,Activator是来自于System.Runtime下的一个静态类,在服务器端激活模式下它可以通过GetObject的方法得到远程对象的一个代理类。
在服务器端激活的模式下你也可以使用new这个方法来创建一个代理类。
但是这里需要注意的是:
什么时候使用Activator.GetObject ,而什么时候使用New,需要根据你的代理类的元数据到底使用哪种格式决定的:
如果你是使用接口的方式的得到代理类的话,那么你就必须通过使用Activator.GetObject方式来的到;
如果你是把宿主服务器的Assembly(DLL形式)直接拷贝到你客户端,而被客户端引用使用的话,那么你就应该使用new这个方法来得到客户端代理类!
二、客户端激活模式
吃饭要紧,回来再写!