利用動態調用方式實現分布式應用(上)
(本文轉載自軟件工程專家網 www.21cmm.com )
蘇洋
CORBA規范中定義動態調用接口(Dynamic Invocation Interface,DII)和動態骨架接口(Dynamic Skeleton Interface,DSI)的目的在于增加分布式應用程序設計的靈活性。
通常,基于客戶端存根程序的情況下,需要預先知道被調用方法的名稱、參數、返回值類型等信息。但是,在實際應用中往往在設計客戶端應用時,不知道服務對象實現的具體細節,甚至服務對象實例還沒有被創建。根據這種情況,CORBA定義了另外一種客戶對象調用服務對象實現方法的方式:客戶端以動態調用接口(DII)方式實現,而服務對象以動態骨架接口(DSI)形式創建。這樣,在分布式應用程序設計時,很大程度上減少了客戶端應用程序創建時對服務對象的依賴程度,提高了分布式應用程序設計的靈活性。
客戶端動態調用接口(DII)
動態調用方式下創建客戶端和服務對象實現應用時不再依靠樁程序和骨架程序對服務對象的引用。因此,在IDL到Java語言映射過程中需要指定映射工具的動態調用映射選項“-dynamic_marshal”,在VisiBroker中映射的方式為:
idl2java -dynamic_marshal filename.idl
在創建基于動態調用的分布式應用程序的客戶端應用時,在客戶端應首先創建請求(Request)對象,并在請求對象中指定服務對象中方法名稱以及應用的參數等。創建請求對象后,以同步形式或異步形式查詢服務對象的運行情況,并在服務對象運行結束后解析返回結果,結束動態調用請求。
在動態調用方式下,客戶端必須向服務對象提出服務請求(Request)。Request對象代表客戶對象向服務對象提出調用請求。創建Request對象的方式有兩種:一是通過對調用對象的引用,用被引用對象的_request方法創建Request對象,然后調用Request對象的add_value方法添加方法調用需要的參數; 另一種方式是調用被引用對象的_create_request方法來創建對服務對象的調用請求。利用_request方法創建請求對象的例子代碼為:
org.omg.CORBA.Request request = serverObject._request(“getName”)
在上面的代碼中創建的請求對象用于調用服務對象的名稱為getName的方法。
服務請求由對服務對象的引用、要調用的服務對象方法名稱和參數列表構成。請求的參數以元素列表的形式實現,其中元素是NamedValue結構類型的實例,該結構定義如下:
typedef unsigned long Flags;
struct NamedValue
{
Identifier name;
any argument;
long len;
Flags arg_modes;
}
其中參數的意義分別為加入列表中的元素的名稱、變量值、變量長度和參數的模式標識。
CORBA為動態調用接口定義了很多方法,用于在客戶端創建調用請求、查詢返回結果和對返回結果進行解析等。下面介紹常用的客戶端實現動態調用的方法:
1. void create_request( in Context ctx,
in Identifier operation,
in NVList arg_list,
inout NamedValue result,
out Request request,
in Flags req_flags)
其中參數分別為調用請求應用的context對象、調用的方法名稱、調用方法的參數、調用返回結果、新的返回請求和請求標志等。
2. boolean poll_response( in Request req)
其中的參數req為用戶創建的服務請求。該方法用于查詢在以異步形式向服務對象發送的服務請求的完成情況。返回TRUE說明請求已經完成,否則說明未完成。
3. get_response() raises (WrongTransaction)
該方法用于查詢以同步方式向服務對象發送的服務請求的完成情況。方法返回調用請求的結果。如果服務對象端的被調用方法沒有完成,則get_response方法一直等待直至請求完成。
類似的方法還有get_next_response,用于在客戶端發送多個調用請求的情況下查詢下一個請求的執行情況。
服務對象動態骨架接口(DSI)
服務對象動態骨架接口(DSI)位于服務對象端,用于動態處理客戶端提出的服務請求。動態骨架接口通過對象適配器接收客戶端服務請求,并將該請求傳遞給服務對象實現。
在處理客戶請求時,服務對象實現不去分析客戶是使用樁方法還是動態調用接口來提出對象服務請求; 同時,發出調用的客戶程序也不去分辨服務對象接收服務請求是不是通過服務對象骨架。
服務對象端CORBA對象結構如下圖所示:
基于動態骨架接口的服務對象實現程序的編寫步驟為:
● 以DynamicImplementation接口為父對象創建服務對象實現程序;
● 實現DynamicImplementation接口的invoke方法,應用接收客戶對象提出的服務對象請求;
● 通過narrow方法獲得對根POA的引用;
● 通過根POA的create_POA方法創建服務POA(POA Servant),在服務POA中指定服務對象方法的實現;
在創建服務對象實現程序時,必須實現抽象類DynamicImplementation中的invoke等方法。該類的定義為:
package org.omg.CORBA;
public abstract class DynamicImplementation
extends org.omg.CORBA.portable.ObjectImpl
{
public abstract void invoke(org.omg.CORBA.ServerRequest request);
}
可以看出:DynamicImplementation抽象類中定義了抽象方法invoke。該方法用于在服務對象實現程序中處理客戶對象提出的服務請求。在該方法中,首先分析request實例中的調用方法名稱,來分析客戶提出的方法在服務對象實現端是否有定義。如果沒有定義,則拋出BAD_OPERATION異常。其代碼為:
if (!request.operation().equals(“getName”))
{
throw new org.omg.CORBA
.BAD_OPERATION();
}
上面的代碼中,通過request對象的operation方法,分析需要調用的方法名稱。因此,可以在程序中判斷該方法是否在服務對象端有實現。在request請求的方法名稱正確的情況下,服務對象實現端應用調用適合的方法來處理用戶請求。
Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=2317
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
