.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
新聞熱點
疑難解答