天天看點

.net Remoting(3)——激活,激活方式

在生成遠端對象時,建立和初始化新對象就是激活。遠端處理系統須始終了解所需的激活類型才能将對象設定為可供用戶端使用。激活有兩種方式:伺服器激活和用戶端激活

伺服器激活

伺服器激活的對象是生存期直接受伺服器直接控制的對象。僅當用戶端對對象進行方法調用時,伺服器應用程式域才會建立這些對象,而不是當用戶端調用new或Activator.GetObject的時候。用戶端請求伺服器激活類型的執行個體時,會在用戶端應用程式域中建立一個代理。伺服器激活類型隻允許使用預設構造器。如果想使用特定的采用參數的構造器建立執行個體的類型,可以使用用戶端激活,也可以動态釋出特定執行個體。

伺服器激活的對象有兩種激活模式:Singleton和SingleCall,這兩種模式又叫已知對象,由枚舉類型:WellKnownObjectMode來辨別。

Singleton類型在任一時刻隻有一個執行個體。所有的用戶端請求都将由這個執行個體提供服務。如果不存在執行個體,則伺服器建立一個,且所有的後來的用戶端請求都将由這個執行個體提供服務。對于單件類型,會關聯到預設的生存期。

SingleCall類型針對每個用戶端請求建立一個執行個體。下一個方法調用将由其他伺服器執行個體提供服務,即使在系統尚未回收前一個執行個體的引用的情況下也是這樣。

類RemotingConfiguration

方法 RegisterWellKnownServiceType 将伺服器上的對象類型注冊為已知類型

public static void RegisterWellKnownServiceType(

    Type type,

    string objectUri,

    WellKnownObjectMode mode)

所有知道已注冊已知對象的URI的客戶都可以擷取該對象的代理,方法是:用ChannelServices注冊信道,然後調用new或Activator.GetObject方法來激活對象。

·當用new來激活對象時,須先要使用RegisterWellKnownClientType方法在用戶端注冊該已知對象類型。調用RegisterWellKonwnClientType方法向遠端處理基礎結構提供遠端對象的位置,使new關鍵字可以建立它。

·當用Activator.GetObject方法來激活已知對象時,須将對象的URL作為參數提供給該方法,是以在這種情況下,不用預先在用戶端注冊。

當調用到達伺服器後,系統從消息中提取URI,檢查遠端處理表以定位與該URI比對的對象的引用,然後執行個體化該對象,将方法調用轉發給該對象。如果是SingleCall,則在方法調用完成後,該對象被銷毀。為每個方法建立對象的一個新執行個體。

Activator.GetObject與new的差別是:Activator.GetObject可以指定URL作為參數,new的時候是從配置中擷取URL

(1)通過Actovator.GetObject方法來擷取代理

Activator類位于System下。它包含一些方法,用于在本地或從遠端建立對象類型,或擷取對現有遠端對象的引用。其中GetObject這個方法有2個重載,方法的意義是:為已知對象或 XML Web services 建立一個代理。

GetObject(Type, String)  為指定類型和 URL 所訓示的已知對象建立一個代理。

GetObject(Type, String, Object)  為指定類型、URL 和通道資料所訓示的已知對象建立一個代理。

以第一個2個參數的方法為例子:第一個參數Type,是在服務端注冊為已知類型的類型,第二個參數是已知對象的URL

服務端:

HttpChannel _channel = new HttpChannel(10001);

ChannelServices.RegisterChannel(_channel,false);

Console.WriteLine("http 通道remoting服務開始……");

RemotingConfiguration.RegisterWellKnownServiceType(

typeof(selfRemoteObject), "selfRemoteObject",

WellKnownObjectMode.Singleton);

用戶端:

public void TestService()

{

selfRemoteObject app =

(selfRemoteObject)Activator.GetObject(

typeof(selfRemoteObject),

"http://localhost:10001/selfRemoteObject");

 Assert.AreEqual(13,app.Plus(3, 10));

}

(2)通過new來建立代理

當用new來激活對象時,先要使用RegisterWellKnownClientType方法在用戶端注冊該已知對象類型。然後使new關鍵字可以建立它。

服務端還是(1)中的服務端

public void TestServiceNew()

RemotingConfiguration.RegisterWellKnownClientType(

    selfRemoteObject app = new selfRemoteObject();

    Assert.AreEqual(13, app.Plus(3, 10));

以上兩種方法在建立代理後,調用方法時,服務端會管理已知類型對象的建立工作,這種生成對象是按預設的構造器(無參)來進行。

用戶端激活

用戶端激活的對象由調用應用程式域控制其生存期的對象,這種情況與應用程式域控制本地對象生存期一樣。

建立用戶端激活對象時,用戶端将調用伺服器。伺服器執行個體化遠端對象,并将對象引用傳回給用戶端。用戶端使用這個引用建立遠端對象的代理。每當用戶端建立用戶端激活對象的執行個體時,都會收到與遠端對象的特定伺服器執行個體進行通信的代理,直至其租約過期,記憶體被回收為止。

采用用戶端激活方式的步驟:

·要在伺服器上建立用戶端激活的對象的執行個體,要知道它的Type

·使用RegisterActivatedServiceType方法在服務端注冊它。

用戶端步驟:

·用戶端先向ChannelServices注冊一個通道,

·通過調用new或Activator.CreateInstance激活對象。

建立用戶端激活類型執行個體的兩種方式:

·以new來進行

·以Activator.CreateInstance的調用中傳遞遠端對象

先準備服務端:

RemotingConfiguration.ApplicationName = "selfRemoteObject";

RemotingConfiguration.RegisterActivatedServiceType

(typeof(selfRemoteObject));

Console.Read();

服務端要通過RegisterActivatedServiceType方法來注冊類型,且先要設定ApplicationName,這個就相當于URL

用戶端

(1)以new來進行

public void TestClientNew()

    HttpChannel _channel = new HttpChannel();

    ChannelServices.RegisterChannel(_channel, false);

RemotingConfiguration.RegisterActivatedClientType

(

typeof(selfRemoteObject),

    selfRemoteObject app1 = new selfRemoteObject();

    Assert.AreEqual(10, app1.Plus(1, 9));

通過new來激活用戶端對象類型,先使用RegisterActivatedClientType方法在用戶端注冊該對象類型,然後new就可以了。

(2)Activator.CreateInstance

如果用CreateInstance,則要提供遠端應用程式的URL作為參數,不用在用戶端注冊類型。如果要用到URL做參數,則URL要封裝在UrlAttribute類執行個體中。

public void TestClientInstance()

    ChannelServices.RegisterChannel(_channel,false);

object[] url={new UrlAttribute

("http://localhost:10001/selfRemoteObject")};

selfRemoteObject app1 =

 (selfRemoteObject)Activator

.CreateInstance(typeof(selfRemoteObject), null, url);

用戶端激活方式可以使用帶參構造器來建立遠端對象執行個體。

修改遠端對象,添加一屬性一個帶參構造器:

public int Unid { get; set; }

public selfRemoteObject() { }

public selfRemoteObject(int iUnid)

    Unid = iUnid;

添加了帶參構造器,要顯示聲明預設的無參構造器。

通過new方法來建立對象執行個體。

selfRemoteObject app1 = new selfRemoteObject();

Assert.AreEqual(0, app1.Unid);

selfRemoteObject app2 = new selfRemoteObject(10);

Assert.AreEqual(10, app2.Unid);

激活方式,是遠端對象執行個體建立的的管理方式。伺服器端激活就是由服務端來管理遠端對象的建立,在這種方式下,當用戶端調用方法時,才建立執行個體;用戶端激活由用戶端來管理遠端對象的建立,在這種方式下,當用戶端發出調用就建立執行個體。

RemotingConfiguration類的類型注冊方法:

RegisterActivatedClientType 将用戶端上的對象 Type 注冊為可在伺服器上激活的類型。

RegisterActivatedServiceType  将服務端上的對象 Type 注冊為可根據請求從用戶端激活的類型。

RegisterWellKnownClientType  将用戶端上的對象 Type 注冊為已知類型(“單個調用”(singlecall) 或 singleton)。

RegisterWellKnownServiceType  将服務端上的對象 Type 注冊為已知類型(“單個調用”(singlecall) 或 singleton)。

斷開

RemotingServices.Disconnect這個方法用于阻止對象通過注冊的遠端處理信道再接收消息。它的參數須是執行個體化的對象(要關閉的),服務端注冊類型要通過Marshal方法來進行:

selfRemoteObject obj=new selfRemoteObject();

RemotingServices.Marshal(obj, "selfRemoteObject");

斷開時,通過Disconnect方法:

RemotingServices.Disconnect(obj);

部落格園大道至簡

http://www.cnblogs.com/jams742003/

轉載請注明:部落格園