參考:百度百科 ♂風(fēng)車車.Net
在訪問(wèn)遠(yuǎn)程類型的一個(gè)對(duì)象實(shí)例之前,必須通過(guò)一個(gè)名為Activation的進(jìn)程創(chuàng)建它并進(jìn)行初始化。這種客戶端通過(guò)通道來(lái)創(chuàng)建遠(yuǎn)程對(duì)象,稱為對(duì)象的激活。
激活分為兩大類:服務(wù)器端激活 客戶端激活
又稱WellKnow(知名對(duì)象)
服務(wù)器應(yīng)用程序在激活對(duì)象實(shí)例之前會(huì)在一個(gè)眾所周知的統(tǒng)一資源標(biāo)識(shí)符(URI)上來(lái)發(fā)布這個(gè)類型。然后該服務(wù)器進(jìn)程會(huì)為此類型配置一個(gè)WellKnown對(duì)象,并根據(jù)指定的端口或地址來(lái)發(fā)布對(duì)象。
服務(wù)器端激活分為:SingleTon模式 SingleCall模式
設(shè)置為SingleTon激活方式,則Remoting將為所有客戶端建立同一個(gè)對(duì)象實(shí)例。當(dāng)對(duì)象處于活動(dòng)狀態(tài)時(shí), SingleTon實(shí)例會(huì)處理所有后來(lái)的客戶端訪問(wèn)請(qǐng)求,而不管它們是同一個(gè)客戶端,還是其他客戶端。SingleTon實(shí)例將在方法調(diào)用中一直維持其狀態(tài)。舉例來(lái)說(shuō),如果一個(gè)遠(yuǎn)程對(duì)象有一個(gè)累加方法(i=0;++i),被多個(gè)客戶端(例如兩個(gè))調(diào)用。如果設(shè)置為SingleTon方式,則第一個(gè)客戶獲得值為1,第二個(gè)客戶獲得值為2,因?yàn)樗麄儷@得的對(duì)象實(shí)例是相同的。如果熟悉asp .Net的狀態(tài)管理,我們可以認(rèn)為它是一種application狀態(tài)。
下面貼代碼:
1.創(chuàng)建遠(yuǎn)程調(diào)用處理的類

using System;using System.Runtime.Remoting.Metadata;/*code 釋迦苦僧*/namespace MessageMarshal{ /*創(chuàng)建發(fā)送消息委托*/ public delegate void SendMessageHandler(string messge); [Serializable] public class TestMessageMarshal : MarshalByRefObject { PRivate Guid ID { get; set; } /*新建對(duì)象實(shí)例時(shí)重新創(chuàng)建標(biāo)識(shí)編號(hào)*/ public TestMessageMarshal() { ID = Guid.NewGuid(); } /*創(chuàng)建發(fā)送消息事件*/ public static event SendMessageHandler SendMessageEvent; /*發(fā)送消息*/ [SoapMethod(xmlNamespace = "MessageMarshal", SoapAction = "MessageMarshal#SendMessage")] public void SendMessage(string messge) { if (SendMessageEvent != null) SendMessageEvent(ID.ToString() + "/t" + messge); } }}View Code2.創(chuàng)建服務(wù)端代碼

using System;using System.Runtime.Remoting;using System.Runtime.Remoting.Channels;using System.Runtime.Remoting.Channels.Http;using MessageMarshal;namespace TestRemotingServer{ /*code:釋迦苦僧*/ class Program { static void Main(string[] args) { /*創(chuàng)建HTTP通道*/ HttpChannel channel = new HttpChannel(8226); /*注冊(cè)通道服務(wù)端*/ ChannelServices.RegisterChannel(channel,false); /*設(shè)置模式為 Singleton */ RemotingConfiguration.RegisterWellKnownServiceType(typeof(TestMessageMarshal),"test", WellKnownObjectMode.Singleton); Console.WriteLine("started ..."); /*接收客戶端事件*/ TestMessageMarshal.SendMessageEvent+=new SendMessageHandler(TestMessageMarshal_SendMessageEvent); Console.Read(); } static void TestMessageMarshal_SendMessageEvent(string messge) { Console.WriteLine(messge); } }}View Code3.創(chuàng)建客戶端代碼

using System;using System.Runtime.Remoting;using System.Runtime.Remoting.Channels;using System.Runtime.Remoting.Channels.Http;using System.Threading;/*code 釋迦苦僧*/namespace TestRemotingClient{ class Program { static void Main(string[] args) { HttpChannel channel = new HttpChannel(); ChannelServices.RegisterChannel(channel, false); /*注冊(cè)通道 的 遠(yuǎn)程處理類型*/ RemotingConfiguration.RegisterWellKnownClientType(typeof(MessageMarshal.TestMessageMarshal), "http://localhost:8226/test"); /*創(chuàng)建消息實(shí)體*/ MessageMarshal.TestMessageMarshal TestMessage = new MessageMarshal.TestMessageMarshal(); while (true) { TestMessage.SendMessage("DateTime.Now:" + System.DateTime.Now.ToString()); Console.WriteLine("send message..."); Thread.Sleep(2000); } } }}View Code4.運(yùn)行服務(wù)端后,開(kāi)啟兩個(gè)客戶端程序,查看結(jié)果如下:

代碼示意中,當(dāng)TestMessageMarshal有新實(shí)例時(shí),其構(gòu)造函數(shù)會(huì)創(chuàng)建不同的標(biāo)識(shí)(GUID),服務(wù)端接收到客戶端的數(shù)據(jù)請(qǐng)求,并將標(biāo)識(shí)編號(hào)輸出到界面,從界面中可以看出,多個(gè)客戶端請(qǐng)求的通道,服務(wù)端都是用一個(gè)通道(一個(gè)實(shí)例)來(lái)進(jìn)行處理的。
SingleCall是一種無(wú)狀態(tài)模式。一旦設(shè)置為SingleCall模式,則當(dāng)客戶端調(diào)用遠(yuǎn)程對(duì)象的方法時(shí), Remoting會(huì)為每一個(gè)客戶端建立一個(gè)遠(yuǎn)程對(duì)象實(shí)例,至于對(duì)象實(shí)例的銷毀則是由GC自動(dòng)管理的。同上一個(gè)例子而言,則訪問(wèn)遠(yuǎn)程對(duì)象的兩個(gè)客戶獲得的都是1。我們?nèi)匀豢梢越梃bAsp .Net的狀態(tài)管理,認(rèn)為它是一種session狀態(tài)。
我們修改服務(wù)端代碼如下,客戶端不需要修改:
/*設(shè)置模式為 SingleCall */ RemotingConfiguration.RegisterWellKnownServiceType(typeof(TestMessageMarshal),"test", WellKnownObjectMode.SingleCall);
開(kāi)啟服務(wù)端,然后開(kāi)啟一個(gè)客戶端,如下
從輸出結(jié)果中可以看出,每次服務(wù)端都會(huì)為每一個(gè)客戶端請(qǐng)求建立一個(gè)遠(yuǎn)程對(duì)象實(shí)例。
與WellKnown模式不同, Remoting在激活每個(gè)對(duì)象實(shí)例的時(shí)候,會(huì)給每個(gè)客戶端激活的類型指派一個(gè)URI。客戶端激活模式一旦獲得客戶端的請(qǐng)求,將為每一個(gè)客戶端都建立一個(gè)實(shí)例引用。SingleCall模式和客戶端激活模式是有區(qū)別的:首先,對(duì)象實(shí)例創(chuàng)建的時(shí)間不一樣。客戶端激活方式是客戶一旦發(fā)出調(diào)用的請(qǐng)求,就實(shí)例化;而SingleCall則是要等到調(diào)用對(duì)象方法時(shí)再創(chuàng)建。其次,SingleCall模式激活的對(duì)象是無(wú)狀態(tài)的,對(duì)象生命期的管理是由GC管理的,而客戶端激活的對(duì)象則有狀態(tài),其生命周期可自定義。其三,兩種激活模式在服務(wù)器端和客戶端實(shí)現(xiàn)的方法不一樣。尤其是在客戶端,SingleCall模式是由 GetObject()來(lái)激活,它調(diào)用對(duì)象默認(rèn)的構(gòu)造函數(shù)。而客戶端激活模式,則通過(guò)CreateInstance()來(lái)激活,它可以傳遞參數(shù),所以可以調(diào)用自定義的構(gòu)造函數(shù)來(lái)創(chuàng)建實(shí)例。
1.修改服務(wù)端代碼

using System;using System.Runtime.Remoting;using System.Runtime.Remoting.Channels;using System.Runtime.Remoting.Channels.Http;using System.Runtime.Remoting.Channels.Tcp;using MessageMarshal;namespace TestRemotingServer{ /*code:釋迦苦僧*/ class Program { static void Main(string[] args) { /*創(chuàng)建HTTP通道*/ HttpChannel channel = new HttpChannel(8226); /*注冊(cè)通道服務(wù)端*/ ChannelServices.RegisterChannel(channel,false); RemotingConfiguration.ApplicationName = "test"; RemotingConfiguration.RegisterActivatedServiceType(typeof(TestMessageMarshal)); Console.WriteLine("started ..."); /*接收客戶端事件*/ TestMessageMarshal.SendMessageEvent+=new SendMessageHandler(TestMessageMarshal_SendMessageEvent); Console.Read(); } static void TestMessageMarshal_SendMessageEvent(string messge) { Console.WriteLine(messge); } }}View Code2.修改客戶端代碼

using System;using System.Runtime.Remoting;using System.Runtime.Remoting.Channels;using System.Runtime.Remoting.Channels.Http;using System.Threading;/*code 釋迦苦僧*/namespace Te
新聞熱點(diǎn)
疑難解答
圖片精選
網(wǎng)友關(guān)注