熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Java編程 >> Java核心技術 >> 正文

簡單介紹.Net遠程方法調用研究

2013-11-23 18:54:47  來源: Java核心技術 

  簡介
  
  遠程方法調用發展到現在已經有以下幾種框架實現DCE/RPCCORBADCOMMTS/COM+Java RMIJava EJBWeb Services/SOAP/XMLRPCNET Remoting本文主要介紹了NET遠程方法調用的原理實現以及與微軟COM/DCOM實現的異同點
  
  框架
  
  Microsoft NET Remoting 提供了一種允許對象通過應用程序域與另一對象進行交互的框架眾所周知Web服務僅僅提供了一種簡單的容易理解的方法來實現跨平台跨語言的交互而DotNet Remoting相對於Web服務就像Asp相對於CGI那樣實現了一種質的轉變DotNet Remoting提供了一個可擴展的框架它可以選擇不同的傳輸機制(HTTP和TCP是內置的)不同的編碼方式(SOAP以及二進制代碼)安全設置(IIS或SSL)同時提供了多種服務包括激活和生存期支持
  
  遠程方法調用
  
  對於遠程方法調用來說最直接的問題恐怕是一個本地方法推而廣之一個本地對象如果放在網絡環境中如何傳遞這個方法的調用返回如何傳遞這個對象的請求雖然對於應用開發人員來說這個並不是必不可少的事但對於我們學習分布式操作系統來說我想這是應該搞清楚的我們知道DCOM協議也被稱為對象RPC它建立在DCE RPC協議基礎上也就是說在網絡傳輸這一層它必須使用特殊的協議另外Windows RPC 機制要求熟悉的類型和使用 IDL 工具的封送處理知識並向開發人員公開 RPC 客戶端和服務器存根的管理Remoting 在為 NET 提供 RPC 時要容易得多而且由於使用簡單易懂的 NET 數據類型從而消除了早期 RPC 機制中存在的類型不匹配的情況(這是一個非常大的威脅)配置為使用 HTTP 或 TCP 協議並使用 XML 編碼的 SOAP 或本機二進制消息格式進行通信開發人員可以構建自定義的協議(通道)或消息格式(格式化程序)並在需要時由 Remoting 框架使用服務器和客戶端組件都可以選擇端口就象可以選擇通信協議一樣由此帶來的一個好處是很容易建立並運行基本的通信
  
  下圖中描述了Net Remoting的五要素
  
  代理在Client端偽裝為Remote Objects並轉發對Remote Objects的調用
  
  Message消息對象包含了執行Remote Methods調用的必要數據參數
  
  Message Sink/Channel Sink在Remote調用中Message Sink允許定制消息處理流程這是Net Remoting內置的可擴展特性
  
  Formatter也是Message Sink用來序列化消息已適於網絡傳輸如SOAP
  
  Transport Channel也是Message Sink用來傳輸序列化的消息到遠程進程如HTTP
  
  當訪問Remote Objects時Client端application並不處理真實對象的引用而是僅僅調用Proxy對象的方法Proxy對象提供與Remote Objects相同的接口偽裝成Remote ObjectsProxy對象自己並不執行任何方法而是以消息對象(Message Object)的形式轉發每一個方法調用給Net Remoting Framework
  
  在類型支持方面DCOM提供了一套復雜的列集和散集機制他建立在RPC的基礎上由於RPC被定義為DCE標准的一部分而DCE RPC定義了所有常用的數據類型的數據表達方法即網絡數據表示法為了使存根(stub)代碼和代理對象能夠正確地對參數和返回結果也進行列集和散集它們應該使用一致的數據表示法NDR以便在不同的操作系統環境下也能夠遠程調用
  
  This figure is from the book named Advanced Net Remoting
  
  反過來我們再看看NET Remoting 強大的類型操作Net Remoting 支持所有托管的類型接口枚舉對象等這通常被稱為多類型保真這裡的關鍵在於如果客戶端和服務器組件都是在應用程序域中運行的 CLR 托管的對象則數據類型的互操作是不成問題的從根本上講我們擁有的是一個封閉的系統會話的兩端可以完全被理解因此我們可以充分利用這一事實處理好用於通信的數據類型和對象
  
  在各種系統並存的情況下我們需要考慮系統之間的互操作性對於可互操作的數據類型我們要謹慎處理例如Web 服務數據類型的定義要基於 XML 架構定義 (XSD) 關於數據類型的說明任何可以使用 XSD 進行描述並可以在 SOAP 上進行互操作的類型都可以使用但是這也確實使得某些數據類型不能使用
  
  代理
  
  代理對象偽裝成一個遠程對象並且向本地提供遠程對象相同的接口客戶端應用程序與處理遠程真實對象的應用(包括內存引用指針等等)都是通過代理對象實現的代理對象當然並不自己完成方法調用它將請求作為消息對象傳給NET Framework在這一方面Net Remoting 和DCOM思想上是一致的當某個客戶端激活一個遠程對象時框架將創建 TransparentProxy 類的一個本地實例(該類中包含所有類的列表與遠程對象的接口方法)因為 TransparentProxy 類在創建時用 CLR 注冊所以代理上的所有方法調用都被運行時截取這時系統將檢查調用以確定其是否為遠程對象的有效調用以及遠程對象的實例是否與代理位於同一應用程序域中如果對象在同一個應用程序域中則簡單方法調用將被路由到實際對象如果對象位於不同的應用程序域中將通過調用堆棧中的調用參數的 Invoke 方法將其打包到 IMessage 對象並轉發到 RealProxy 類中此類(或其內部實現)負責向遠程對象轉發消息TransparentProxy 類和 RealProxy 類都是在遠程對象被激活後在後台創建的但只有 TransparentProxy 返回到客戶端在代理對象創建時需要引用Client端的Messag Sink ChainSink Chain的第一個Sink對象的引用保存在RealProxy對象的Identity屬性如下圖所示
  
  所以在下面這段代碼調用new或者GetObject獲得對象後對象obj將會指向
  
  TransparentProxy對象
  
  HttpChannel channel = new HttpChannel();
  
  ChannelServicesRegisterChannel(channel);
  
  SomeClass obj = (SomeClass) ActivatorGetObject(
  
  type of(SomeClass)
  
  );
  
  消息
  
  當一次函數調用指向遠程對象的引用時TransparentProxy創建一個MessageData對象並且將它傳給RealProxy對象的PrivateInvoke()調用RealProxy相應地生成一個新的Message對象並且以MessageData對象為參數調用其InitFields()方法Message將會解析MessageData對象中地指針進行相應地函數調用當處理結束時將會返回一個包含回應消息的IMessage對象RealProxy將會調用它自己的HandleReturnMessage()方法該方法檢查參數並且調用PropagateOutParameters()方法當處理結束後RealProxy將會從它的PrivateInvoke()方法中返回IMessage將會返回給TransparentProxyCLR保證函數返回值與其返回格式相符所以對於應用程序來說它僅僅認為這是一個一般方法的調用返回這正是分布式的最終要求
  
  可以看到NET Remoting與DCOM的底層機制已經完全不同了DCOM的一次方法調用需要經過列集(marshaling)和散集(unmarshaling)的處理包括創建代理對象和轉載存根代碼等但是可以看到NET做為DCOM的下一代在基本思想上和DCOM是一脈相承的在我學習到現在的體會看來NET面向Web服務的RPC機制的確是一大革新讓我們看看IMessage怎麼進行傳遞的
  
  這是一個消息穿過Transport Channel(也就是Message Sink)的實例
  
  首先是SOAP遠程調用的HTTP請求
  
  POST /MyRemoteObjectsoap HTTP/
  
  UserAgent: Mozilla/+(compatible; MSIE ; Windows ; MS NET
  
  Remoting;
  
  MS NET CLR )
  
  SOAPAction:
  
  #
  
  setValue
  
  ContentType: text/xml; charset=utf
  
  ContentLength:
  
  Expect: continue
  
  Connection: KeepAlive
  
  Host: localhost
  
  然後是一個對於一個遠程對象setValue(int):
  
  POST /MyRemoteObjectsoap HTTP/
  
  UserAgent: Mozilla/+(compatible; MSIE ; Windows ; MS NET
  
  Remoting;
  
  MS NET CLR )
  
  SOAPAction:
  
  #
  
  setValue
  
  ContentType: text/xml; charset=utf
  
  ContentLength:
  
  Expect: continue
  
  Connection: KeepAlive
  
  Host: localhost
  
  <SOAPENV:Envelope
  
  xmlns:xsi=instance
  
  xmlns:xsd=
  
  xmlns:SOAPENC=
  
  xmlns:SOAPENV=
  
  SOAPENV:encodingStyle=
  
  xmlns:i=
  
  >
  
  <SOAPENV:Body>
  
  <i:setValue id=ref>
  
  <newval>
From:http://tw.wingwit.com/Article/program/Java/hx/201311/25973.html
    推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.