1、DCOM
COM的進程透明特性表現在組件對象和客戶程序即可以擁有各自的進程空間,也可以共享同一個進程空間,COM負責把客戶的調用正確傳到組件對象中,並保證參數傳遞的正確性。組件對象和客戶代碼不必考慮調用傳遞的細節,只要按照一般的函數調用的方式實現即可。如果進一步拓展進程透明特性,考慮組件對象與客戶程序運行在不同計算機上的情形,把進程透明性拓展為位置透明性,形成分布式組件對象模型,簡稱為DCOM。
DCOM是COM的擴展,它可以支持不同計算機上組件對象與客戶程序之間或者組件對象之間的相互通信,這些計算機可以在局域網內、廣域網上、 Internet上。對於客戶程序而言,組件程序所處的位置是透明的,我們不必編寫任何處理遠程調用的代碼,因此,DCOM也是COM的無縫擴展。 DCOM處理了底層網絡協議的所有細節。
2、從COM轉向DCOM
進程內組件與客戶程序之間的通信過程比較簡單。本地進程外組件與客戶程序之間的通信並不是直接進行的,而是用到了操作系統支持的一些跨進程通信方法。
DCOM只是簡單地把本地跨進程通信用一個網絡協議傳輸過程來代替,只是中間數據傳遞的路線更長一些。當然,網絡通信比單機系統環境下的跨進程通信要脆弱得多,所以為了保證協作過程的可靠性以及程序對異常事件的應變能力,客戶程序和組件程序需要考慮更多的細節。
3、DCOM對象的定位
客戶程序調用COM庫的基礎創建函數(比如CoGetClassObject)創建遠程組件對象需要知道遠程機器名和對象CLSID。
有兩種方法可以得到遠程對象的機器名信息:一是在創建函數的參數中指定COSERVERINFO結構,二是使用DCOM配置工具指定遠程機器名。
COM庫的創建函數得到了遠程對象的位置信息後,再把對象創建的任務交給SCM,由SCM通過RPC與遠程機器進行通信。SCM(程序名為 Rpcss.exe)也是COM庫的一部分,但它是一個單獨的進程。SCM負責創建新的COM對象,也負責建立組件對象與客戶程序之間的連接。如果要創建遠程對象,它會通過RPC調用遠程機器上的SCM,由遠程機器上的SCM啟動組件進程,並創建組件對象,然後返回到客戶機器。
當然,遠程組件對象被創建之後,它在返回到客戶機器的途中,還要經過列集和散集的處理,包括創建代理對象和裝載存根代碼等,這些處理與本地進程外組件對象的處理完全一致。一旦組件對象被創建完成之後,客戶與組件之間的通信不再經過SCM,而是直接通過代理對象和存根對象以及COM庫提供的底層傳輸機制來完成。
4、列集與散集
列集與散集是實現COM組件對象跨進程特性的關鍵技術,它包括標准列集法和自定義列集法。同樣的技術也適用於DCOM組件對象與客戶程序之間的通信,兩者的區別在於列集數據包的傳遞方式有所不同,對於本地組件對象使用LPC傳遞,而對於DCOM組件對象使用RPC傳遞。
DCOM提供了一套復雜的列集和散集機制,它建立在RPC的基礎上。由於RPC被定義為DCE(分布式計算系統)標准的一部分,而DCE RPC定義了所有常用數據類型的數據表達方式,即網絡數據表示法(NDR,network data representation)。為了使存根代碼和代理對象能夠正確地對參數和返回結果進行列集和散集,它們應該使用一致的數據表示法NDR,以便在不同的操作系統環境下也能夠遠程調用。
5、對象RPC
DCOM協議也被稱為對象RPC(ORPC,object remote procedure call ),它建立在DCE RPC協議的基礎上,可用於各種基於組件的分布式系統。ORPC建立了一套面向對象的遠程調用規范,指定了如何在網絡上進行調用、對對象的引用如何表示和如何維護。ORPC協議已經被作為Internet草案遞交到IETF(Internet Engineering Task Force , Internet 工程部)。
在Internet或Intranet網絡環境下,ORPC仍使用標准的RPC數據包,附加上專用於DCOM的一些信息――接口指針標識符(IPID,interface point identifier)、版本信息和擴展信息――作為調用和返回的附加參數進行傳送,其中IPID表示調用被處理的遠程機器上特定對象的特定接口。 DCOM客戶程序必須周期性地“pinging”遠程機器上的對象,以便保證客戶與對象一直處於連接狀態。
6、DCOM特性
DCOM可以作為分布式應用系統的基本架構,客戶程序與DCOM組件對象之間形成了客戶/服務器關系,進一步可構成多層軟件模型。DCOM組件具有COM 組件的一些基本特性,包括重用性、語言無關性等。而位置透明性 是DCOM的一個基本特性。DCOM的其他特性如下:
(1)可伸縮性。一方面,DCOM利用操作系統本身的可伸縮性;另一方面,DCOM提供了靈活的配置方案,允許不同的組件對象允許在不同的服務器上,DCOM的位置透明性保證了這種變化可以不必修改組件源程序。
(2)可配置性。安裝和管理是分布式軟件系統的兩個重要環節。DCOM提供了一個圖形界面的配置工具程序(DCOMCNFG.EXE),可使客戶程序和組件程序在不改變代碼的情況下適應不同的網絡環境。
(3)安全性。DCOM使用了Windows NT提供的可擴展安全性框架,在非NT平台上實現的DCOM也包括了一個與NT兼容的安全提供器。DCOM實現的安全性分為訪問安全性和激活安全性,訪問安全性指定那些用戶可以調用組件對象,激發安全性指定哪些用戶可以在一個新進程中創建新的對象。
(4)協議無關性。
(5)平台獨立性
7、對象激活
激活(activation)一個組件對象包括兩種情形:一是創建新的組件對象,二是建立已有組件對象與客戶之間的連接。
COM擴展到DCOM之後,遠程對象的創建過程有所不同。為了標識一個遠程對象,僅僅提供一個128位的GUID還不夠,還必須提供遠程對象所在的機器名,也稱為遠程服務器名“RemoteServerName”。
(1)創建DCOM組件方法一
通過DCOM配置工具指定遠程服務器名,這種方式使得DCOM組件具有位置透明性。在Windows系統平台上,遠程服務器名字RemoteServerName值被保存在系統注冊表HKEY_CLASSES_ROOTAPPID鍵下。
從CLSID和AppID鍵的結構可以看出,每個AppID可用於多個組件對象,通常它代表了由多個CLSID共享的進程,該進程中的所有對象共享同樣的配置信息,包括遠程服務器名以及安全信息。在DCOM中引入AppID概念可以避免太多的注冊表關鍵字。
(2)創建DCOM組件方法二
用第一種方法並不是總能滿足應用的要求,有些應用要求在程序運行過程中控制要連接的服務器,比如多人游戲程序、網絡遠程管理工具等。對於這樣的應用,DCOM允許在創建函數中指定遠程服務器名字。可以指定遠程服務器名字的創建函數:CoCreateInstanceEx、 CoGetClassObject、CoGetInstanceFromFile、CoGetInstanceFromeIStorage。
在程序中指定服務器名字的另外一個功能是實現分布式應用系統的動態負載平衡。目前DCOM還很難以實現自動負載平衡特性,但我們可以建立一個分派服務組件對象,所有的客戶都創建指定機器上的分派服務組件對象,由它創建另一個真正實現應用功能的遠程對象,在把此遠程對象返回給客戶程序,以後客戶程序不再使用分派服務組件對象,而直接調用遠程對象。而分派服務組件對象可以根據當前的負載狀態,從一組服務器中選擇負載最輕的服務器作為目標,創建遠程對象。
8、遠程創建進程內組件:代理進程(surrogate)
為了遠程運行進程內組件即DLL組件,要求在遠程機器上有代理進程(surrogate process)。除了可以遠程啟動進程內組件之外,代理進程還提供了下面的特性:
l 進程內組件程序中的嚴重錯誤只影響代理進程,不會使客戶進程崩潰;
l 一個代理進程可以同時為多個客戶提供服務;
l 客戶可以保護自己避免靠不住的組件程序代碼,只訪問組件程序提供的服務;
l 在代理進程中運行進程內服務可使DLL享有代理進程的安全性。
Windows引進了缺省的代理進程,以及編寫自定義代理進程的協議規范。缺省實現的代理進程是一個混合線程模型、偽COM服務程序。當多個DLL組件被裝入到單個代理進程時,該進程按照注冊表中指定的線程模型對每個DLL組件對象進行實例化。如果一個DLL組件對象支持兩種線程模型,則COM選擇自由線程模型。COM即可以控制DLL組件程序的卸載,也可以終止代理進程。
如果一個進程內組件滿足下列條件,則它將被裝入代理進程:
l 系統注冊表中,在組件對象的CLSID關鍵字下必須要指定AppID值,以及對應的AppID關鍵字;
l 客戶程序在創建對象實例時,必須設置CLSTX_LOCAl _SERVER標志;
l 組件對象的CLSID關鍵字下不指定LocalServer32、LocalServer、LocalService值;
l 組件對象的CLSID關鍵字包含InProvServer32子鍵;
l 在InProcServer32子鍵中指定的DLL文件必須存在;
l 組件對象對應的AppID鍵下指定DllSurrogate值。
如果組件對象的CLSID鍵下的LocalServer、LocalServer32或LocalService值指示了EXE的存在,則EXE程序將被優先執行,COM不再啟動代理程序。
9、利用名字對象(moniker)連接到遠程對象實例
通常COM對象實例是不可相互替代到,或者說不可相互交換的。它通過自己特有的狀態區別於同一類的其他對象實例。
在第8章中介紹的COM命名和綁定機制對於遠程對象同樣適用。
10、連接管理——遠程對象生存期的控制
COM控制對象的生存期最基本的機制是引用計數,利用IUnknown的AddRef和Release成員函數控制對象的生存期。DCOM優化了遠程對象的AddRef和Release的調用。優化過程使用了OXID(object exporter identifier ,對象管理標識符)對象。OXID是一個64位值,通過OXID可以把RPC串綁定調用到它們的目標IPID。但是,在執行調用之前,調用進程必須把 OXID轉譯成為底層RPC可以解釋的一組綁定。
在每台支持DCOM的機器上,都有一個被稱為OXID解析器(OXID Resolver)的服務,它負責向客戶提供用於連接到OXID的RPC串綁定信息,也負責接收遠程發來的“pinging”信息。OXID解析器之間通過RPC進行通信,它實現了RPC接口IOXIDResolver(不是COM接口)。
11、連接管理——pinging機制
如果不考慮客戶進程可能會非正常終止,則利用遠程引用計數控制對象生存期已經足夠了。為了檢測客戶程序是否非正常終止,DCOM提供了一種簡單的方法 “pinging”。在現在實現的DCOM版本中,pingPeriod=2(分)且numPingsToTimeOut=3,這些值不能被改變。
12、連接管理——連接點管理
許多實際的分布式應用都需要在兩個對象之間進行雙向通信。由於DCOM是對COM的無縫擴展,在第6章中介紹的COM提供的連接點機制同樣適用於遠程對象的情形。
13、連接管理——連接傳遞
用分派服務組件對象來實現分布式應用的負載平衡特性實際上用到了連接傳遞特性。
連接傳遞不等於遠程對象創建的傳遞,DCOM不支持位置透明方式下對象創建的傳遞過程,但可以利用連接傳遞特性,通過程序控制服務器名字的方式實現遠程對象創建的傳遞。
14、並發管理——線程模型
COM本身並沒有線程模型,可以認為COM借用了Windows操作系統提供的線程模型,Win32程序設計模型把線程分成UI線程和輔助線程,相對應地,COM把線程分成套間線程和自由線程。套間線程使用CoInitialize API函數執行COM庫的初始化,COM在套間線程內部創建了一個隱藏的窗口,此窗口的窗口過程函數負責把客戶對套間中的組件對象的調用發送到正確的成員函數中。
15、並發管理——消息過濾器
COM和DCOM的線程模型使我們了解到了客戶程序與組件對象調用過程中的線程切換,但調用可能會阻塞程序,甚至使得客戶程序無法正常進行。為此,COM提供了消息過濾機制,它既可用於客戶程序,也可用於組件程序,允許它們對於入調用和出調用有所選擇。
COM把調用分為三類:第一種是同步調用,這是最常見的調用類型,客戶調用組件對象,一直等到對象執行完所有功能後再返回;第二種是異步調用,客戶調用組件對象,但不等到對象執行完功能就馬上返回,以後對象通過出接口通知客戶程序,這也就是我們在第6章介紹的可連接對象機制;第三種為輸入同步調用,被調用對象必須在放棄控制之前返回,以便保證用戶界面不受影響,也就是說,在調用執行過程中,對象不能調用任何可能會進入消息循環的函數。
16、DCOM安全模型
DCOM安全性建立在底層安全提供器基礎上,有些操作系統可以支持多個安全提供器,DCOM和RPC也可以同時支持多個安全提供器。所有的安全提供器有一個共同點,它們提供了一種表示安全角色(一般為用戶賬號)的方法、一種鑒定安全角色(一般通過口令或私有鑰匙)的方法,以及管理安全角色和其鑒定數據的一套機制。
17、DCOM安全模型——安全性策略
(1)訪問安全性和激發安全性。
(2)對象的安全身份。
(3)保護數據。
(4)鑒定級別。
(5)模仿級別。
18、DCOM安全模型——安全性配置
DCOM提供了多種保護應用程序的方法,一方面,DCOM可以強制使用安全性而不用任何對象或對象的客戶程序做任何工作,對象的安全性設置可以在外部配置並且DCOM會自動強制使用。另一方面,DCOM把它完整的安全性結構暴露給開發者,因而客戶和對象都可以通過程序控制其安全策略。