雖然在遊戲開發中,很少使用DCOM/COBRA分布式元件技術。但是作為一種分布式技術,這裡也分析一下存在的問題。
分布式元件技術是一種CS結構,其出現,是為了簡化網絡程式設計,開發者不再需要關心具體如何進行底層通信。目前比較有代表性的有兩種:DCOM和COBRA。DCOM使用ORPC機制,COM伺服器建立對象類的執行個體,一個COM對象可以具有多個接口,分别代表不同的觀察角度和不同的對象行為。用戶端擷取對象接口的指針,通過指針調用相關的方法。
COBRA是由OMG(Object Manage Group)提出的,其核心是ORB(Object Request Broker)。作為一個透明的總線式模型,可以與本地或者遠端的對象進行互動。COBRA對象對外呈現一組接口,用戶端擷取對象的引用,通過引用進行方法的調用。ORB負責查找對象的實作,發送請求并處理傳回結果。
兩種元件模型都采用CS模式的通信。為了調用一個服務,用戶端需要調用遠端對象實作的方法。伺服器端提供的服務,封裝成為一個對象,對象的接口使用IDL(Interface Definition Language)描述。用戶端通過調用IDL中定義的方法與伺服器端進行互動,不用關心實際對象的實作。支援面向對象的一些特性,例如:資料封裝,多态,繼承。COBRA支援多重繼承,DCOM不支援,但是一個對象可以有多個接口。
為了調用一個遠端的方法,用戶端調用本地的樁函數,樁函數将參數封裝成為請求,将請求發送給伺服器端。伺服器端将請求傳遞給Server Stub,對參數進行解包,并調用實際的函數。在DCOM中,用戶端的樁稱為proxy,伺服器端的樁稱為stub;在COBRA中,用戶端的樁稱為stub,伺服器端的樁稱為skeleton。
假設有一種Grid對象服務,Grid對象維護一個二維的整數,支援兩組方法:第一組是get和set,可以設定某個格子上的數值;第二組是reset,複位某個格子上的數值。則對于COBRA,需要定義三個接口,接口Grid1支援get和set;接口Grid2支援reset;接口Grid繼承Grid1,Grid2。使用DCOM,則定義兩種IGrid1和IGrid2。
采用DCOM調用,則用戶端端的處理步驟如下:
1. 用戶端調用COM庫函數CoCreateInstance,使用CLSID_Grid和IID_IGrid1作為參數。
2. COM庫請求伺服器建立對象
3. 伺服器端COM擷取指向CLSID_Grid的類工廠指針,調用其CreateInstance函數。
4. 類工廠建立一個對象,然後伺服器端調用QueryIntreface擷取指向IID_IGrid1接口的指針。
5. COM庫将指向pIGrid1接口的指針傳回給客戶。
6. 用戶端調用pIGrid1接口的get方法。
采用COBRA調用,則用戶端端的處理步驟如下:
1. 用戶端調用樁函數grid::_bind()。
2. ORB向Server發起請求
3. 伺服器端建立執行個體,調用CORBA::BOA::impl_is_ready(),通知ORB對象已經準備好。
4. ORB向用戶端傳回對象的引用
5. 用戶端調用對象的方法。
在上面的處理步驟中每個步驟,COM庫或者ORB都需要進行很多操作,是以調用的效率不高,隻能夠進行粗粒度的調用。例如一個服務上有幾十個對象,如果通過上述方法擷取對象的内容并進行顯示,處理和流程将會多麼複雜。
對象引用在用戶端應用中建立,并且是動态建立的,是以當伺服器端元件是細粒度,對象很多時,這種代價是非常高的。
相比Web Service,WSDL描述的服務方法參數和傳回值,類似于元件對外的接口,但是在進行Web Service進行調用時,不需要建立對象,也沒有對象的概念。而是直接使用URL,定位到了需要調用的伺服器端的對象。是以,Web Service與元件模型相比,調用需要的互動要少一些。
在DCOM和COBRA中,由于對象的建立導緻互動很多,不适合于細粒度的模型。但是如果将伺服器端元件的對象預先建立好,并引入對象管理功能,在用戶端通路伺服器端時,一次性的在用戶端建立相應的對象,則可以解決這個問題,如下圖:
DCOM和COBRA在開發和部署上都相對複雜,影響了其發展和應用。