.Net组件程序设计之远程调用(二)
引用封送对象激活类型两种,
一种是客户端激活类型,一种是服务器端激活.
客户端激活对象
客户端激活方式:当客户端创建一个远程对象时,客户端得到的是一个新的实例引用,新的实例可以在内存中维持状态,并且可以使用参数化构造函数来激活远程对象。
服务器激活模式single-call
SingleCall激活方式:当客户端使用一个服务器激活方式为SingleCall的对象时,.NET为每个方法调用创建一个新对象,在方法执行完毕后,对象则被销毁,客户端虽然维持着对远程对象的引用,但是真实对象已经被销毁了。
服务器激活Singleton
Singleton激活方式:所有客户端共享一个远程对象。
下面为大家演示几段示例,就详细的清楚每一种激活方式的作用了。
1 using System.Runtime.Remoting; 2 using System.Runtime.Remoting.Messaging; 3 namespace RemoteServer 4 /// <summary> 5 /// 服务端 6 /// </summary> 7 public class MyClass : MarshalByRefObject 8 { 9 public MyClass()10 {11 _count++;12 string mes = AppDomain.CurrentDomain.FriendlyName;13 Console.WriteLine(mes);14 }15 16 PRivate int _count = 0;17 18 public event EventHandler NumberChanged;19 20 public void Count()21 {22 _count++;23 Console.WriteLine(AppDomain.CurrentDomain.FriendlyName + "_" + _count.ToString());24 }25 26 public void OnNumberChanged(int num)27 {28 if (NumberChanged != null)29 {30 NumberChanged(num, null);31 }32 }33 }34 35 public class EventMehtodClass : MarshalByRefObject36 {37 [OneWay]38 public void OnNumberChanged(object sender, EventArgs e)39 {40 if (sender != null)41 {42 Console.WriteLine(sender.ToString());43 }44 }45 }
1 宿主服务端(服务器端) 2 using System.Runtime.Remoting; 3 using System.Runtime.Remoting.Channels; 4 using System.Runtime.Remoting.Channels.Http; 5 using System.Runtime.Remoting.Channels.Tcp; 6 using System.Runtime.Remoting.Channels.ipc; 7 using System.Runtime.Remoting.Services; 8 using RemoteServer; 9 10 namespace RemoteServerHost11 12 #region 编程式 宿主服务端注册 信道和对象类型13 Console.WriteLine("开始Tcp注册信道");14 IChannel tcpChannel = new TcpChannel(8003);15 ChannelServices.RegisterChannel(tcpChannel, false);//注册Tcp类型信道16 Console.WriteLine("Tcp信道注册完成————————————————");17 Console.WriteLine("开始 服务器激活类型SingleCall模式的宿主服务器端类型注册");18 RemotingConfiguration.RegisterWellKnownServiceType(typeof(MyClass), "RWCTmyclass",WellKnownObjectMode.SingleCall);19 Console.WriteLine("类型注册完成");20 #endregion21 22 Thread.Sleep(new TimeSpan(0, 2, 0));23 Console.WriteLine("释放Tcp信道");24 ChannelServices.UnregisterChannel(tcpChannel);
这里所用的激活方式是 服务器SingleCall激活方式,通过RemotingConfiguration.RegisterWellKnownServiceType()方法来注册类型,第二个参数为统一资源标识符(URI),很好理解就是字面的意思,远程对象就是资源,标识资源的一个符号(名称),有了它,客户端在调用远程对象的时候才知道具体在哪。因为是服务器激活方式所以URI是在包含在注册类型的方法中的,而如果是客户端激活类型注册的话,则使用RemotingConfiguration.RegisterActivatedServiceType(typeof(MyClass));
有的朋友会问了,这样统一资源标识符不是没设置吗?是的,确实没有设置,客户端激活类型注册的时候URI是这样设置
1 RemotingConfiguration.applicationName = "RWCTmyclass";
1 客户端(调用端) 2 using System.Runtime.Remoting; 3 using System.Runtime.Remoting.Channels; 4 using System.Runtime.Remoting.Channels.Http; 5 using System.Runtime.Remoting.Channels.Tcp; 6 using System.Runtime.Remoting.Channels.Ipc; 7 using System.Runtime.Remoting.Services; 8 using RemoteServer; 9 10 namespace RemoteClient11 12 #region 编程式本地注册13 Thread.Sleep(new TimeSpan(0, 0, 7));//便于调,使当前客户端线程阻塞7秒,确保宿主服务端已经运行14 string url = "tcp://localhost:8003/RWCTmyclass";15 Console.WriteLine("开始客户端注册类型");16 RemotingConfiguration.RegisterWellKnownClientType(typeof(MyClass), url);17 #endregion18 19 20 //类型使用21 MyClass myclass = new MyClass();22 myclass.Count();23 MyClass myclass1 = new MyClass();24 myclass1.Count();
图 1
因为这里使用的是服务器SingleCall类型模式激活的,所以对象状态是不保存的,就跟上面那一小节定义的一样,只有在方法调用的时候才会被创建,方法调用完毕则会被释放销毁,但是也可以在宿主服务端使用变量来记录状态。现在可以在宿主服务端(服务器端)注册类型的时候把激活模式换成Singleton的再来看一下结果:这是编程式的示例代码,下面给大家演示配置式的。
1 宿主服务端(服务器端) 2 using System.Runtime.Remoting; 3 using System.Runtime.Remoting.Channels; 4 using System.Runtime.Remoting.Channels.Http; 5 using System.Runtime.Remoting.Channels.Tcp; 6 using System.Runtime.Remoting.Channels.Ipc; 7 using System.Runtime.Remoting.Services; 8 9 using System.Threading;10 11 using RemoteServer;12 13 namespace RemoteServerHost14 15 #region 配置式宿主服务端注册 信道和对象类型16 Console.WriteLine("开始注册Http信道");17 RemotingConfiguration.Configure(AppDomain.CurrentDomain.FriendlyName + ".config");18 Console.WriteLine("Http信道注册完成————————————————");19 #endregion
这里只要使用.NET给我们提供的RemotingConfiguration类型中的Configure()方法来加载配置文件就行了,注册信道的类型,远程对象的激活方式和模式都是在配置文件中注册的,来看配置文件信息:
1 <?xml version="1.0" encoding="utf-8" ?> 2 <configuration> 3 <system.runtime.remoting> 4 <application> 5 <channels> 6 <channel ref="http" port="8004"/> 7 </channels> 8 <service> 9 <wellknown mode="Singleton" type="RemoteServer.MyClass,RemoteServer" objectUri="RTMyClass" />10 </service>11 </application>12 </system.runtime.remoting>13 </configuration>
这里配置文件中,是准备注册http类型的信道,并且把远程对象注册为服务器激活类型(wellKnow)Singleton激活模式,宿主服务端的就这么多,接下来看客户端的.
1 客户端 2 using System.Runtime.Remoting; 3 using System.Runtime.Remoting.Channels; 4 using System.Runtime.Remoting.Channels.Http; 5 using System.Runtime.Remoting.Channels.Tcp; 6 using System.Runtime.Remoting.Channels.Ipc; 7 using System.Runtime.Remoting.Services; 8 9 using System.Threading;10 11 using RemoteServer;12 13 namespace RemoteClient14 15 #region 配置式本地注册16 Thread.Sleep(new TimeSpan(0, 0, 7));17 Console.WriteLine("开始客户端注册类型");18 RemotingConfiguration.Configure(AppDomain.CurrentDomain.FriendlyName + ".config", false);19 #endregion20 //类型使用21 Console.WriteLine(AppDomain.CurrentDomain.FriendlyName);22 MyClass myclass = new MyClass();23 myclass.Count();24 MyClass myclass1 = new MyClass();25 myclass1.Count();
跟宿主服务端的一样,使用Configure()方法来注册远程对象,但是本地的配置文件怎么配置呢?不着急的,一起来看:
1 <?xml version="1.0" encoding="utf-8" ?> 2 <configuration> 3 <system.runtime.remoting> 4 <application> 5 <client> 6 <wellknown type="RemoteServer.MyClass,RemoteServer" url="http://localhost:8004/RTMyClass"/> 7 </client> 8 </application> 9 </system.runtime.remoting>10 </configuration>
客户端 要注册的 远程对象类型 的 激活类型(客户端激活、服务器端激活) 是要跟宿主服务端的相对应。这次换了Singleton模式
图2
1 宿主服务端: 2 using System.Runtime.Remoting; 3 using System.Runtime.Remoting.Channels; 4 using System.Runtime.Remoting.Channels.Http; 5 using System.Runtime.Remoting.Channels.Tcp; 6 using System.Runtime.Remoting.Channels.Ipc; 7 using System.Runtime.Remoting.Services; 8 using System.Threading; 9 10 using RemoteServer;11 namespace RemoteServerHost12 13 14 #region 远程回调15 Console.WriteLine("开始Tcp注册信道");16
新闻热点
疑难解答