Remoting服务和客户程序编写模式
理解一下,可以归纳出:
1、客户端激活的时间是在客户端请求的时候,而服务端激活远程对象的时间是在调用对象方法的时候
远程对象修改如下:
using System;
namespace RemoteObject
{
public class MyObject:MarshalByRefObject
{
private int i=0;
![]()
public MyObject()
{
Console.WriteLine("激活");
}
![]()
public int Add(int a,int b)
{
return a+b;
}
![]()
public int Count()
{
return ++i;
}
}
}
服务端配置文件:
<configuration>
<system.runtime.remoting>
<application name="RemoteServer">
<service>
<activated type="RemoteObject.MyObject,RemoteObject"/>
</service>
<channels>
<channel ref="tcp" port="9999"/>
</channels>
</application>
</system.runtime.remoting>
</configuration>
客户端程序:
using System;
namespace RemoteClient
{
class MyClient
{
[STAThread]
static void Main(string[] args)
{
//RemoteObject.MyObject app =
(RemoteObject.MyObject)Activator.GetObject(typeof(
RemoteObject.MyObject),System.Configuration.ConfigurationSettings.AppSettings["ServiceURL"]);
RemoteObject.MyObject app=
(RemoteObject.MyObject)Activator.CreateInstance(typeof(
RemoteObject.MyObject),null,new object[]
{
new System.Runtime.Remoting.Activation.UrlAttribute(
System.Configuration.ConfigurationSettings.AppSettings["ServiceURL"])});//Console.WriteLine(app.Count());
Console.ReadLine();
}
}
}
客户端配置文件:
<configuration>
<appSettings>
<add key="ServiceURL" value="tcp://localhost:9999/RemoteServer"/>
</appSettings>
</configuration>
这里的uri按照服务端配置文件中application元素定义的RemoteServer来写,运行程序可以看到,在客户端启动的时候服务端就输出了“激活”,我们再转回知名模式进行测试发现只有运行了方法才会在服务端输出“激活”。
2、客户端激活可以调用自定义的构造方法,而不像服务端激活只能使用默认的构造方法
把客户端代码修改如下:
RemoteObject.MyObject app=
(RemoteObject.MyObject)Activator.CreateInstance(
typeof(RemoteObject.MyObject),new object[]{10},new object[]
{
new System.Runtime.Remoting.Activation.UrlAttribute(
System.Configuration.ConfigurationSettings.AppSettings["ServiceURL"])});Console.WriteLine(app.Count());
这里看到我们在CreateInstance方法的第二个参数中提供了10作为构造方法的参数。在服务端激活模式我们不能这么做。
远程对象构造方法修改如下:
public MyObject(int k)
{
this.i=k;
Console.WriteLine("激活");
}
毫无疑问,我们运行客户端发现输出的是11而不是1了。
3、通过上面的例子,我们运行多个客户端发现出现的永远是11,因此,客户端激活模式一旦获得客户端的请求,将为每一个客户端都建立一个实例引用。
总结
1、Remoting支持两种远程对象:知名的和客户激活的。知名的远程对象使用了uri作为标识,客户程序使用这个uri来访问那些远程对象,也正式为什么称作知名的原因。对知名的对象来说2种使用模式:SingleCall和Singleton,对于前者每次调用都会新建对象,因此对象是无状态的。对于后者,对象只被创建一次,所有客户共享对象状态,因此对象是有状态的。另外一种客户端激活对象使用类的类型来激活,uri再后台被动态创建,并且返回给客户程序。客户激活对象是有状态的。
2、对于Singleton对象来说需要考虑伸缩性,Singleton对象不能在多个服务器上被部署,如果要跨服务器就不能使用Singleton了。
备注:个人习惯原因,在我的例子中服务端的配置都是用config文件的,客户端的配置都是基本用程序方式的。
使用配置文件的优点:无需重新编译就可以配置通道和远程对象,编写的代码量比较少。
使用程序定制的优点:可以获得运行期间的信息,对程序调试有利。
