.NET Remoting 體系結(jié)構(gòu)評(píng)估
Pat Martin
Microsoft Corporation
2003年5月
適用于:
Microsoft? .NET Framework
Microsoft? .NET Remoting
摘要: 本文適用于要將 .NET Remoting 用于分布式多層應(yīng)用程序設(shè)計(jì)的人員。文章從開(kāi)發(fā)人員的角度介紹了該技術(shù)的功能。開(kāi)發(fā)人員曾得益于這項(xiàng)技術(shù)所提供的方便的 RPC 機(jī)制,也曾感受過(guò)其不足之處帶來(lái)的不便。本文假設(shè)讀者熟悉 .NET Remoting,即使沒(méi)有實(shí)際使用過(guò),至少對(duì)其概念也有所了解。
產(chǎn)品特性 一節(jié)對(duì)使用 Remoting 進(jìn)行設(shè)計(jì)的人員很有用, 最佳方法 一節(jié)適用于使用 Remoting 進(jìn)行構(gòu)建的人員, Remoting 和 Web 服務(wù) 一節(jié)試圖消除有關(guān)“在何時(shí)選用何種技術(shù)”的困惑, 摘要 是對(duì)內(nèi)容的精煉。
目錄
概述
.NET Remoting 被譽(yù)為管理應(yīng)用程序域之間的 RPC 的首選技術(shù)。應(yīng)用程序域是公共語(yǔ)言運(yùn)行庫(kù)的隔離單元,它們是在進(jìn)程內(nèi)創(chuàng)建并運(yùn)行的。這與 CLR 和非 CLR 托管的進(jìn)程之間的進(jìn)程間通信(互操作)不同。后一種類型的 RPC 通信(特別是 Web 上的)一般被認(rèn)為是 Web 服務(wù)領(lǐng)域的問(wèn)題。遺憾的是,這種看似清楚的區(qū)分,卻由于可以在 IIS 下集成 .Net Remoting 服務(wù)器而變得模糊,正如 Microsoft .NET Remoting 框架簡(jiǎn)介 一文中所述:
“通過(guò)在 IIS 中集成 .NET Remoting 對(duì)象,可以將其作為一種 Web 服務(wù)提供……”
一些 Microsoft 客戶可能對(duì) .NET Remoting 或多或少有些疑惑。我經(jīng)常聽(tīng)到有人問(wèn)“應(yīng)該在什么時(shí)候使用 Remoting?”、“Remoting 何時(shí)會(huì)支持 NTLM?”、“如何保證遠(yuǎn)程會(huì)話的安全?”、“COM+ 怎么樣?”以及“Remoting 如何管理事務(wù)?”
除了回答這些問(wèn)題,本文還將介紹一些使用 .NET Remoting 的最佳方法,并概要介紹當(dāng)前可以獲得的功能。 摘要 預(yù)測(cè)了該技術(shù)的未來(lái)發(fā)展方向,特別是有關(guān) Web 服務(wù)和新興的全局 XML Web Service 體系結(jié)構(gòu) (GXA) 規(guī)范的問(wèn)題。
產(chǎn)品特性 一節(jié)的信息大部分來(lái)自 TechED N.Z. 2002,這次演示重點(diǎn)介紹了在分布式解決方案中使用 Remoting 的不同方法,闡明了 Remoting 的優(yōu)點(diǎn),也提到了一些不足之處。
最佳方法 一節(jié)源于在多層 .NET 應(yīng)用程序中使用 Remoting 的個(gè)人經(jīng)驗(yàn),其中介紹了很多在開(kāi)發(fā)過(guò)程中用到的簡(jiǎn)單易行的最佳方法。
某些節(jié)包括了根據(jù)非正式談話整理得到的資料,談話的對(duì)象是對(duì)該技術(shù)及其發(fā)展方向都有深刻理解的 Microsoft 內(nèi)部人員,但這里提供的信息決不代表未來(lái)的產(chǎn)品發(fā)布計(jì)劃或安排。
產(chǎn)品特性
本節(jié)介紹 .NET Remoting 的功能和產(chǎn)品特性。
客戶端/服務(wù)器通信
.NET Remoting 提供了一種很有用的方法,用于管理跨應(yīng)用程序域的同步和異步 RPC 會(huì)話。遠(yuǎn)程對(duì)象代碼可以運(yùn)行在服務(wù)器上(如服務(wù)器激活的對(duì)象和客戶端激活的對(duì)象),也可以運(yùn)行在客戶端上(其上的遠(yuǎn)程對(duì)象已經(jīng)通過(guò)客戶端/服務(wù)器的連接進(jìn)行了序列化)。在任何一種情況下,只要完成初始化和配置(這并不困難),即可使用非常簡(jiǎn)單的編程語(yǔ)言,只需要少量的代碼。遠(yuǎn)程對(duì)象(在按引用封送時(shí)是代理的對(duì)象)的使用對(duì)程序員是透明的。例如,早期的 Windows RPC 機(jī)制要求熟悉的類型和使用 IDL 工具的封送處理知識(shí),并向開(kāi)發(fā)人員公開(kāi) RPC 客戶端和服務(wù)器存根的管理。Remoting 在為 .NET 提供 RPC 時(shí)要容易得多,而且由于使用簡(jiǎn)單易懂的 .NET 數(shù)據(jù)類型,從而消除了早期 RPC 機(jī)制中存在的類型不匹配的情況(這是一個(gè)非常大的威脅)。
默認(rèn)情況下,可以將 Remoting 配置為使用 HTTP 或 TCP 協(xié)議,并使用 XML 編碼的 SOAP 或本機(jī)二進(jìn)制消息格式進(jìn)行通信。開(kāi)發(fā)人員可以構(gòu)建自定義的協(xié)議(通道)或消息格式(格式化程序),并在需要時(shí)由 Remoting 框架使用。服務(wù)器和客戶端組件都可以選擇端口,就象可以選擇通信協(xié)議一樣。由此帶來(lái)的一個(gè)好處是,很容易建立并運(yùn)行基本的通信。
但是,在選擇通信類型時(shí)還要考慮狀態(tài)管理。本節(jié)接下來(lái)將介紹 Remoting 提供的各種通信選項(xiàng)及其相關(guān)的設(shè)計(jì)含義。
服務(wù)器激活的對(duì)象
“服務(wù)器激活的對(duì)象”是由服務(wù)器控制生存期的對(duì)象。它們只在客戶端調(diào)用對(duì)象的第一個(gè)方法時(shí),根據(jù)需要由服務(wù)器創(chuàng)建。服務(wù)器激活的對(duì)象只支持默認(rèn)的構(gòu)造函數(shù)。要對(duì)遠(yuǎn)程對(duì)象使用參數(shù)化的構(gòu)造函數(shù),可以使用“客戶端激活”或“動(dòng)態(tài)發(fā)布”(參見(jiàn)下文)。服務(wù)器激活的對(duì)象也被稱為眾所周知的對(duì)象類型,因?yàn)槠湮恢?(URL) 是預(yù)先發(fā)布和已知的。服務(wù)器激活的對(duì)象有兩種激活模式: Singleton 和 SingleCall ,下面將介紹這兩種模式。要?jiǎng)?chuàng)建服務(wù)器激活類型的實(shí)例,可以通過(guò)編程的方法配置應(yīng)用程序,也可以進(jìn)行靜態(tài)配置。服務(wù)器激活的配置相當(dāng)簡(jiǎn)單,例如,以下代碼片段
<service> <wellknown mode="SingleCall" type="Hello.HelloService, Hello" objectUri="HelloService.soap" /> </service>
描述了一個(gè)服務(wù)器激活的 (wellknown) 類型,其激活方式設(shè)置為 SingleCall 。有關(guān)配置服務(wù)器激活的 Remoting 的詳細(xì)信息,請(qǐng)參閱 MSDN 上 .Net Framework Developer's Guide 中的“Server-Side Registration”。
Singleton
這些對(duì)象遵循傳統(tǒng)的 Singleton 設(shè)計(jì)模式,在這種模式中,任何時(shí)候內(nèi)存中都只有一個(gè)實(shí)例,所有客戶端都接受該實(shí)例提供的服務(wù)。但要注意,這些類型都有與之相關(guān)的默認(rèn)生存期(請(qǐng)參閱下文的 對(duì)象生存期管理 一節(jié))。這意味著對(duì)于可進(jìn)行遠(yuǎn)程處理的類,客戶端不必總是接收對(duì)這個(gè)類的同一實(shí)例的引用。后一種情況對(duì)狀態(tài)管理很有意義,也是這種 Remoting 模式與傳統(tǒng)的 Singleton 模式(要求對(duì)象標(biāo)識(shí)相同)的不同之處。如果您的設(shè)計(jì)需要使用傳統(tǒng)的 Singleton 狀態(tài)管理模式,有兩種方法可以解決此問(wèn)題。一種方法是忽略默認(rèn)的對(duì)象租用行為,以便“在主機(jī)應(yīng)用程序域運(yùn)行時(shí)始終”將對(duì)象保存在內(nèi)存中。以下代碼片段說(shuō)明了如何做到這一點(diǎn):
public class MyClass : MarshalByRefObject { public override Object InitializeLifetimeService() { return null; } }
如上所述,這種機(jī)制將對(duì)象鎖定到內(nèi)存中,防止對(duì)象被回收,但只能在主機(jī)應(yīng)用程序運(yùn)行期間做到這樣。對(duì)于 IIS 集成,如果集成 Remoting 會(huì)話的 IIS 或 IIS 進(jìn)程被回收(很多原因可以導(dǎo)致這種現(xiàn)象),那么對(duì)象將被破壞。
要完全依賴 Remoting 的線程安全的 Singleton 狀態(tài)數(shù)據(jù),我們需要做三件事:
- 忽略租用機(jī)制,使租用成為無(wú)限期的,如上所述。
- 將遠(yuǎn)程服務(wù)器集成在我們自己設(shè)計(jì)的進(jìn)程中,例如,可以完全控制其生存期的系統(tǒng)服務(wù)。雖然此進(jìn)程也可以被回收,但與回收 IIS 輔助進(jìn)程相比,其操作更明顯,更易察覺(jué)。有關(guān)此機(jī)制的詳細(xì)信息,請(qǐng)參閱下文的 產(chǎn)品特性 一節(jié)。
- 將遠(yuǎn)程服務(wù)器開(kāi)發(fā)為線程安全的服務(wù)器,因?yàn)檫@樣可以使用多個(gè)線程來(lái)完成客戶端的并發(fā)請(qǐng)求。這意味著,管理并發(fā)將寫入共享資源并通常關(guān)注對(duì)靜態(tài)內(nèi)存的共享訪問(wèn)。
SingleCall
SingleCall 遠(yuǎn)程服務(wù)器類型總是為每個(gè)客戶端請(qǐng)求設(shè)置一個(gè)實(shí)例。下一個(gè)方法調(diào)用將改由其他實(shí)例進(jìn)行服務(wù)。從設(shè)計(jì)角度看, SingleCall 類型提供的功能非常簡(jiǎn)單。這種機(jī)制不提供狀態(tài)管理,如果您需要狀態(tài)管理,這將是一個(gè)不利之處;如果您不需要,這種機(jī)制將非常理想。也許您只關(guān)心負(fù)載平衡和可伸縮性而不關(guān)心狀態(tài),那么在這種情況下,這種模式將是您理想的選擇,因?yàn)閷?duì)于每個(gè)請(qǐng)求都只有一個(gè)實(shí)例。如果愿意,開(kāi)發(fā)人員可以向 SingleCall 對(duì)象提供自己的狀態(tài)管理,但這種狀態(tài)數(shù)據(jù)不會(huì)駐留在對(duì)象中,因?yàn)槊看握{(diào)用新的方法時(shí)都將實(shí)例化一個(gè)新的對(duì)象標(biāo)識(shí)。
動(dòng)態(tài)發(fā)布
還需要考慮服務(wù)器激活方法的最后一個(gè)類型,即動(dòng)態(tài)發(fā)布。這是一種服務(wù)器激活的類型,通過(guò)提供程序化的發(fā)布機(jī)制,可以對(duì)對(duì)象結(jié)構(gòu)進(jìn)行更多的控制。它允許在特定的 URL 發(fā)布特定的對(duì)象,并可以選擇使用參數(shù)化的構(gòu)造函數(shù)。從結(jié)構(gòu)上講,這種類型可以看作是服務(wù)器激活的 Singleton 類型的一個(gè)微小變形。有關(guān) 動(dòng)態(tài)發(fā)布 的信息,請(qǐng)參閱 .NET Framework Developer's Guide 。
客戶端激活的對(duì)象
“客戶端激活的對(duì)象”是當(dāng)客戶端調(diào)用 new 或 Activator.CreateInstance() 時(shí)在服務(wù)器上創(chuàng)建的。客戶端本身使用生存期租用系統(tǒng),可以參與到這些實(shí)例的生存期中。這種激活機(jī)制能夠提供最廣泛的設(shè)計(jì)靈活性。如果使用客戶端激活,當(dāng)客戶端試圖激活對(duì)象時(shí),激活請(qǐng)求將發(fā)送到服務(wù)器。這種機(jī)制允許使用參數(shù)化的構(gòu)造函數(shù)和針對(duì)每個(gè)客戶端的連接狀態(tài)管理。使用客戶端激活,每個(gè)客戶端接受其特定的服務(wù)器實(shí)例提供的服務(wù),從而簡(jiǎn)化了多個(gè)調(diào)用時(shí)對(duì)象狀態(tài)的保存過(guò)程。但使用這些對(duì)象時(shí)一定要謹(jǐn)慎,因?yàn)楹苋菀淄洉?huì)話是分布式的,對(duì)象實(shí)際上不僅在進(jìn)程之外,而且在多層應(yīng)用程序的情況下,還有可能在計(jì)算機(jī)之外(在 Internet 上設(shè)置一個(gè)屬性并不過(guò)分)。實(shí)用而不花哨的接口應(yīng)該成為這里的準(zhǔn)則:為了提高性能,我們可能需要在高度結(jié)合與松散耦合之間進(jìn)行權(quán)衡。要?jiǎng)?chuàng)建客戶端激活類型的實(shí)例,可以通過(guò)編程的方法配置應(yīng)用程序,也可以進(jìn)行靜態(tài)配置。在服務(wù)器上進(jìn)行客戶端激活的配置相當(dāng)簡(jiǎn)單,例如,以下代碼片段
<service> <activated type="Hello.HelloService, Hello" objectUri="HelloService.soap" /> </service>
描述了一個(gè)客戶端激活的類型。請(qǐng)注意,我們不再需要 URL,因?yàn)閷?duì)于客戶端激活的類型,類型本身就足以激活了。另外, wellknown 標(biāo)記已被 activated 標(biāo)記替代。有關(guān)配置客戶端激活的 Remoting 的詳細(xì)信息,請(qǐng)參閱 MSDN 上 .Net Framework Developer's Guide 中的“Server-Side Registration”。
擴(kuò)展性
在處理遠(yuǎn)程方法調(diào)用的過(guò)程中,.NET Remoting 將格式化的“消息”沿 Remoting 的“通道”從客戶端發(fā)送到服務(wù)器。消息格式和通道本身都是完全可擴(kuò)展和可自定義的。默認(rèn)的通道或格式化程序都可以由自定義構(gòu)建的組件所替代。消息在傳輸過(guò)程中可以在多個(gè)“接收點(diǎn)”被截取和更改,允許對(duì)消息進(jìn)行自定義的處理(例如消息加密)。 .NET Framework Developer's Guide (Sinks and Sink Chains) 中介紹了自定義機(jī)制,而且 Internet 上已經(jīng)出現(xiàn)了一些自定義的通道和格式化程序(例如,Named Pipe 通道的實(shí)現(xiàn))。大多數(shù)人對(duì)這種擴(kuò)展性并不感興趣,因?yàn)樵摷夹g(shù)提供的默認(rèn)格式化程序和通道已經(jīng)可以在最廣的范圍內(nèi)使用(即 TCP 和 HTTP,尤其是與 SOAP 消息格式化程序一起使用)。但是在最初的設(shè)計(jì)階段,需要考慮各種解決方案選項(xiàng),記住這種功能還是有必要的。
異常傳播
.NET Remoting 完全支持跨 Remoting 邊界的異常傳播,這是對(duì)使用錯(cuò)誤代碼,如 DCOM 的重大改進(jìn)。
使用 Remoting 異常,最好將異常類標(biāo)記為可序列化的并實(shí)現(xiàn) ISerializable 接口。這樣,可以跨 Remoting 邊界對(duì)異常進(jìn)行正確地序列化,也可以在構(gòu)造過(guò)程中將自定義的數(shù)據(jù)添加到異常中。對(duì)于需要遠(yuǎn)程處理以及在使用中要保持一致的異常,最好定義您自己的異常類。確保使用此方法能捕獲所有異常并進(jìn)行正確傳播,而且不允許未處理的異常跨過(guò) Remoting 邊界。
對(duì)象生存期管理
.NET Remoting 為管理遠(yuǎn)程對(duì)象的生存期提供了功能強(qiáng)大的機(jī)制。如果我們的服務(wù)器對(duì)象不保留任何狀態(tài)(如 SingleCall 對(duì)象),那么不必關(guān)注此進(jìn)程,只需讓 Remoting 基礎(chǔ)結(jié)構(gòu)完成要完成的工作即可,需要時(shí),對(duì)象將作為垃圾被回收。如果我們保留狀態(tài),無(wú)論是服務(wù)器激活的 Singleton 還是客戶端激活的對(duì)象,我們可能都要參與生存期管理進(jìn)程:對(duì)象租用。我們已經(jīng)看到很小程度的參與,使用了一種簡(jiǎn)單(且有用)的方法,就是忽略 InitializeLifetimeService 方法,如以上對(duì) Singleton 的介紹中所述。這就使我們能夠在集成對(duì)象的進(jìn)程運(yùn)行期間始終保留對(duì)象。那么,這個(gè)對(duì)象生存期進(jìn)程如何工作呢?
Remoting 提供的對(duì)象管理機(jī)制基于租用原則:您永遠(yuǎn)不會(huì)擁有一個(gè)對(duì)象,只是借用它,只要持續(xù)支付就可以一直使用它。此過(guò)程將在下文中進(jìn)一步介紹。但是,首先要簡(jiǎn)單介紹一下在 COM 領(lǐng)域中是如何處理對(duì)象清理的。DCOM 綜合使用 ping 和引用計(jì)數(shù)兩種方法來(lái)確定對(duì)象是否仍在運(yùn)行,這樣做不僅容易出錯(cuò),而且對(duì)網(wǎng)絡(luò)帶寬的要求很高。使用引用計(jì)數(shù)時(shí),最壞的情況是從來(lái)不會(huì)被完全理解,最好的情況也是很脆弱。過(guò)去(現(xiàn)在仍是)要對(duì)引用計(jì)數(shù)應(yīng)用一些簡(jiǎn)單的規(guī)則才能使其發(fā)揮作用。COM 對(duì)象的 IUnknown 接口包括了 AddRef 和 Release 方法,需要由開(kāi)發(fā)人員在適當(dāng)?shù)臅r(shí)候調(diào)用。有時(shí)程序員弄錯(cuò)了,結(jié)果造成對(duì)象沒(méi)被刪除,還導(dǎo)致相關(guān)的內(nèi)存泄露。
相反,Remoting 基于租用的生存期管理系統(tǒng)綜合利用了租用、負(fù)責(zé)人和租用管理器。每個(gè)應(yīng)用程序域都包含一個(gè)租用管理器,它將每個(gè) Singleton 或客戶端激活的對(duì)象的租用對(duì)象引用保存在其域中。每個(gè)租用可以有零個(gè)或多個(gè)相關(guān)的負(fù)責(zé)人,負(fù)責(zé)人能夠在租用管理器確定租用過(guò)期時(shí)重新租用。這種租用功能是由 Remoting 基礎(chǔ)結(jié)構(gòu)通過(guò) ILease 接口提供的,通過(guò)調(diào)用 InitializeLifetimeService 獲得,如上文所述。 ILease 接口定義了很多用于管理對(duì)象生存期的屬性:
- InitialLeaseTime。 確定租用最初的有效期。
- RenewOnCallTime。 在每個(gè)方法調(diào)用后,更新此時(shí)間單元的租用。
- SponsorshipTimeout。 負(fù)責(zé)人通知租用過(guò)期后,Remoting 要等待的時(shí)間。
- CurrentLeaseTime。 距租用到期的時(shí)間(只讀)。
租用過(guò)期后,租用管理器將通知所有租用負(fù)責(zé)人,詢問(wèn)他們是否要更新租用。如果不更新,將釋放相關(guān)的對(duì)象引用。
負(fù)責(zé)人是可以為遠(yuǎn)程對(duì)象更新租用的對(duì)象。要成為負(fù)責(zé)人,您的類必須從 MarshalByRefObject 中導(dǎo)出并實(shí)現(xiàn) ISponsor 接口。一個(gè)租用可以有多個(gè)負(fù)責(zé)人,一個(gè)負(fù)責(zé)人也可以參與多個(gè)租用。
有關(guān)使用這些接口進(jìn)行編程的租用管理機(jī)制,請(qǐng)參閱 Lifetime Leases (英文)上的 .NET Framework Developer's Guide 文檔,這里就不重復(fù)介紹了。但值得注意的是,這種功能強(qiáng)大的機(jī)制只是對(duì)管理有狀態(tài)的遠(yuǎn)程對(duì)象的生存期有意義。如上所述,您或者完全忽略它,利用它在其進(jìn)程容器運(yùn)行時(shí)將對(duì)象保存在內(nèi)存中,或者完全參與到租用機(jī)制中。
遠(yuǎn)程服務(wù)器集成
有很多方法可以集成 .NET 遠(yuǎn)程服務(wù)器,主要分為兩大類,如下所述。
ASP.NET 下的 IIS 集成
在 IIS 下集成遠(yuǎn)程服務(wù)器端對(duì)象的能力是作為標(biāo)準(zhǔn)功能提供的。它有很多優(yōu)勢(shì),包括支持安全性和可伸縮性。
要在 IIS 下集成對(duì)象:
- 開(kāi)發(fā)遠(yuǎn)程類并從 MarshalByRefObject 中繼承(或?qū)㈩惵暶鳛榭尚蛄谢?
- 使用 IIS 管理器創(chuàng)建一個(gè)虛擬的 Web 應(yīng)用程序。
- 將包含您的類的程序集放到虛擬 Web 應(yīng)用程序的 bin 子文件夾中。
- 創(chuàng)建一個(gè) web.config 文件以保存 Remoting 服務(wù)器的配置定義,并將它放置到 Web 應(yīng)用程序的虛擬根目錄中。
就這么簡(jiǎn)單。但是,您應(yīng)該了解一些限制:
- 不能為 IIS 集成指定應(yīng)用程序名稱,因?yàn)樗翘摂M應(yīng)用程序名稱。
- 必須使用 HHTP 通道。
- 如果 Remoting 客戶端也是一個(gè) Web 應(yīng)用程序,則啟動(dòng)時(shí)必須調(diào)用 RemotingConfiguration.Configure ,它通常在 Global.asax 文件的 Application_Start 方法中。不能使用 <client> 標(biāo)記來(lái)自動(dòng)配置客戶端 Web 應(yīng)用程序。
- 不要指定端口,因?yàn)?IIS 會(huì)進(jìn)行端口分配。如果需要,您仍可以使用 IIS 管理來(lái)為虛擬應(yīng)用程序指定端口。
Remoting 應(yīng)用程序域?qū)⒓稍?Aspnet_wp.exe 輔助進(jìn)程中,默認(rèn)情況下,它將采用該進(jìn)程的標(biāo)識(shí)。
注意: 目前 ASP.NET 中有一個(gè)錯(cuò)誤,要求將 Aspnet_wp.exe 輔助進(jìn)程的進(jìn)程標(biāo)識(shí)設(shè)置為“system”或本地計(jì)算機(jī)帳戶,默認(rèn)設(shè)置中,machine.config 中的“machine”配置不正確,導(dǎo)致在域控制器的 IIS 下集成時(shí),ASP.NET 應(yīng)用程序出現(xiàn)錯(cuò)誤 500“內(nèi)部服務(wù)器錯(cuò)誤”。可以論證的是,該錯(cuò)誤是由于缺乏說(shuō)明如何適當(dāng)?shù)嘏渲糜?jì)算機(jī)帳戶的文檔所造成的。
在 IIS 下集成有很多功能上的優(yōu)勢(shì):默認(rèn)情況下,可以提供伸縮性、線程、審核、身份驗(yàn)證、授權(quán)和安全通信等功能。ASP.NET 輔助進(jìn)程一直在運(yùn)行,并且可以使用 machine.config 中的 <processModel> 元素進(jìn)行線程和錯(cuò)誤管理方面的微調(diào)。簡(jiǎn)而言之,IIS 的優(yōu)勢(shì)和功能都可用于遠(yuǎn)程服務(wù)器。
但它也有一些缺點(diǎn):您必須使用比 TCP 速度慢的 HTTP。另外,IIS 可能循環(huán)執(zhí)行 ASP.NET 輔助進(jìn)程,這將破壞所有 Singleton 的狀態(tài)。對(duì)您來(lái)說(shuō),這可能是問(wèn)題也可能不是問(wèn)題,要取決于您的設(shè)計(jì)需要,因?yàn)榭蛻舳说南乱粋€(gè)調(diào)用將重新啟動(dòng) Singleton。您可以將 IIS 配置為不循環(huán)執(zhí)行輔助進(jìn)程,但這種能力很有限,特別是在 IIS 5 中,而且可能造成更進(jìn)一步的影響。這里最根本的意思是,如果要求遠(yuǎn)程服務(wù)器的安全性,那么無(wú)疑要使用 IIS 集成。至于性能,只有在系統(tǒng)測(cè)試/使用過(guò)程中實(shí)際察覺(jué)到問(wèn)題時(shí),才需要考慮,而且總能在硬件上找到解決問(wèn)題的辦法。
IIS 下要考慮的身份驗(yàn)證問(wèn)題
身份驗(yàn)證選項(xiàng)
.NET Remoting 沒(méi)有自己的安全模式:身份驗(yàn)證和授權(quán)是由通道和主機(jī)進(jìn)程執(zhí)行的,在這種情況下則由 IIS 執(zhí)行。Windows 身份驗(yàn)證可用于 Remoting,配置方法是在 web.config 中設(shè)置 <authentication mode="Windows"/>。不能使用表單或 Passport 身份驗(yàn)證,因?yàn)?Remoting 客戶端不能訪問(wèn) Cookie,也不能重新定向到登錄頁(yè)面(因?yàn)檫h(yuǎn)程服務(wù)器是為非交互使用設(shè)計(jì)的)。
將憑據(jù)傳遞到遠(yuǎn)程對(duì)象
如果遠(yuǎn)程對(duì)象是 IIS 集成的(在 ASP.NET 輔助進(jìn)程中)并配置為使用 Windows 身份驗(yàn)證,則必須使用通道的憑據(jù)屬性指定要使用的憑據(jù),否則將導(dǎo)致不傳遞任何憑據(jù)就進(jìn)行遠(yuǎn)程調(diào)用。這種疏忽是 HTTP 訪問(wèn)拒絕響應(yīng)的常見(jiàn)原因。要使用集成遠(yuǎn)程對(duì)象代理的進(jìn)程(Remoting 客戶端進(jìn)程)的憑據(jù),請(qǐng)將通道的憑據(jù)屬性設(shè)置為由進(jìn)程憑據(jù)緩存維護(hù)的 DefaultCredentials 。這可以使用通道元素(用于 Web 客戶端),即 <channel ref="http" useDefaultCredentials="true"/> 公開(kāi)地完成,也可以使用以下代碼通過(guò)編程方式完成:
IDictionary channelProperties; channelProperties = ChannelServices.GetChannelSinkProperties(proxy); channelProperties["credentials"] = CredentialCache.DefaultCredentials;
要隨遠(yuǎn)程對(duì)象調(diào)用一起傳遞“特定的”憑據(jù),請(qǐng)禁用默認(rèn)憑據(jù),即設(shè)置 <channel ref="http" useDefaultCredentials="false"/> 并使用以下代碼:
IDictionary channelProperties = ChannelServices.GetChannelSinkProperties(proxy); NetworkCredential credentials; credentials = new NetworkCredential("username", "password", "domain"); ObjRef objectReference = RemotingServices.Marshal(proxy); Uri objectUri = new Uri(objectReference.URI); CredentialCache credCache = new CredentialCache(); // 用 Negotiate、Basic、Digest、 // Kerberos 或 NTLM 替換 authenticationType credCache.Add(objectUri, "authenticationType", credentials); channelProperties["credentials"] = credCache; channelProperties["preauthenticate"] = true;
注意: 將 preauthenticate 屬性設(shè)置為真(如上所述)將使 WWW 身份驗(yàn)證標(biāo)頭隨初始請(qǐng)求傳遞。這將停止 Web 服務(wù)器拒絕對(duì)原始請(qǐng)求的訪問(wèn),并對(duì)隨后的請(qǐng)求執(zhí)行身份驗(yàn)證。
在 IIS 之外集成
在 IIS 之外進(jìn)行遠(yuǎn)程集成的方法有很多,如下所示。
在控制臺(tái)應(yīng)用程序中集成
開(kāi)發(fā)人員可以編寫一個(gè)啟動(dòng) Remoting 基礎(chǔ)結(jié)構(gòu)的控制臺(tái)應(yīng)用程序,然后把它“留在附近”。把它留在附近的唯一原因,是因?yàn)樗闪诉h(yuǎn)程調(diào)用的應(yīng)用程序域。編寫一個(gè)這樣的程序非常簡(jiǎn)單:只需調(diào)用 RemotingConfiguration.Configure 方法,把您的遠(yuǎn)程主機(jī)配置文件傳遞給它,然后只需等待由某個(gè)事件,比如按鍵或收到特定的消息等來(lái)終止進(jìn)程。
這種方法的優(yōu)勢(shì)是不要求使用中間層上的 IIS,但不可以隨時(shí)生成,因此適用于演示、開(kāi)發(fā)和測(cè)試。這并不是說(shuō)它一無(wú)是處,只是用途有限而已。
在 GUI 應(yīng)用程序中集成
開(kāi)發(fā)人員還可以編寫一個(gè)啟動(dòng) Remoting 基礎(chǔ)結(jié)構(gòu)的 Windows GUI 應(yīng)用程序,然后把它“留在附近”。同樣,需要繼續(xù)執(zhí)行的唯一原因是它包含集成了遠(yuǎn)程調(diào)用的應(yīng)用程序域。它的開(kāi)發(fā)方法與控制臺(tái)應(yīng)用程序的方法相同:Remoting 主機(jī)可以直接啟動(dòng),也可以根據(jù)用戶的交互操作啟動(dòng)。同樣,這種方法也具有不需要中間層上的 IIS 的優(yōu)勢(shì),并可用于演示和測(cè)試。對(duì)該程序做一些變化可以得到對(duì)等網(wǎng)絡(luò)(邏輯)winforms 應(yīng)用程序,例如,聊天類型的應(yīng)用程序。同樣,該程序的使用范圍也很有限。
在系統(tǒng)服務(wù)中集成
這種可能性非常有意思,因?yàn)?Remoting 基礎(chǔ)結(jié)構(gòu)提供的功能竟沒(méi)有系統(tǒng)服務(wù)概念本身所提供的功能多。系統(tǒng)服務(wù)可以配置為在計(jì)算機(jī)啟動(dòng)時(shí)啟動(dòng),并保留在周圍直到您讓它們離開(kāi),這對(duì)于遠(yuǎn)程集成是非常理想的。請(qǐng)注意,通過(guò)為虛擬應(yīng)用程序設(shè)置“高隔離模式”,也可以將 IIS 應(yīng)用程序配置為具有類似行為。關(guān)于這個(gè)問(wèn)題還有很多內(nèi)容值得探討,本文就不討論了。客戶詢問(wèn)了許多關(guān)于這種機(jī)制的難題,包括它的用途。首先,介紹一些它的優(yōu)點(diǎn):我們已經(jīng)介紹了服務(wù)本身的好處;另外,我們可以完全控制主機(jī)進(jìn)程的激活,例如,可以選擇是使用動(dòng)態(tài)發(fā)布還是使用客戶端激活;不需要 IIS,因?yàn)槲覀兛梢约虞d用戶配置文件,并可以使用 TCP 上的二進(jìn)制編碼消息獲得良好的性能。
但它的缺點(diǎn)也很多。首先,如果需要,您要構(gòu)建自己的身份驗(yàn)證和授權(quán)機(jī)制。 .NET Remoting Security Solution, Part 1:Microsoft.Samples.Security.SSPI Assembly (英文)一文完整詳細(xì)地介紹了 .NET Remoting 的安全性解決方案:“……實(shí)現(xiàn)了 SSPI 的托管包裝,提供了驗(yàn)證客戶端和服務(wù)器以及簽名和加密在二者之間發(fā)送的消息所需的核心功能。”這無(wú)疑是一筆寶貴的資源,它提供了一種添加此功能的機(jī)制,這非常有用。但問(wèn)題是它并不是一個(gè)受支持的產(chǎn)品,而是一個(gè)提供補(bǔ)充功能的“非正式”方法。而且對(duì)開(kāi)發(fā)人員還有一點(diǎn)威脅,因?yàn)樵摻鉀Q方案要依賴格式化程序和通道的可擴(kuò)展性。所有這些都需要回避,要獲得功能,必須向 Remoting 配置添加條目以說(shuō)明使用 Windows NT Challenge/Response (NTLM)。但此類安全機(jī)制很有可能要加入到 .NET Remoting 的未來(lái)版本中。
系統(tǒng)服務(wù)也需要具有可伸縮性,并可作為 Remoting 服務(wù)器重新使用,因?yàn)槎鄬拥姆植际綉?yīng)用程序?qū)⑿枰@些功能。例如,如果沒(méi)有 IIS,集成服務(wù)將不得不管理自己的審核和授權(quán),而這二者都是 IIS 在標(biāo)準(zhǔn)情況下附帶的。
由于這些原因,系統(tǒng)服務(wù)集成機(jī)制的用途很有限,也許要在一個(gè)受約束的環(huán)境下使用,這種環(huán)境中的消息要排隊(duì)進(jìn)行單獨(dú)交換,而安全性不是問(wèn)題,或者還可以使用 TCP 上的 IPSec。
企業(yè)服務(wù)管理
為了使遠(yuǎn)程組件參與到 COM+ 環(huán)境中(并在 COM+ 的上下文中運(yùn)行),需要從 ServicedComponent 中繼承。 ServicedComponent 和 System.EnterpriseServices 命名空間中提供的其他功能都允許 CLR 組件指定多個(gè) COM+ 屬性,如表示事務(wù)要求和服務(wù)器進(jìn)程執(zhí)行的屬性等。再加上嚴(yán)格命名機(jī)制和使用 regsvcs 命令,遠(yuǎn)程組件可以成為整個(gè) COM+ 環(huán)境中的一部分。
假設(shè)遠(yuǎn)程組件需要從 MarshalByRefObject 中繼承,COM+ 組件需要從 ServicedComponent 中繼承(而且在 .NET 托管代碼中沒(méi)有多重繼承功能),如何實(shí)現(xiàn)這一點(diǎn)呢?幸運(yùn)的是, ServicedComponent 是從 ContextBoundObject 派生的,而后者又是從我們需要的 MarshalByRefObject 派生的。在 Remoting 上直接構(gòu)建 COM+ 集成是完全可以的,而且確實(shí)能夠獲得由企業(yè)服務(wù)提供的顯而易見(jiàn)的優(yōu)勢(shì),例如對(duì)象池、分布式的事務(wù)支持和基于角色的安全性等。但是,如何做到這一點(diǎn)以及這樣的方法對(duì)未來(lái)驗(yàn)證的體系結(jié)構(gòu)會(huì)產(chǎn)生什么樣的影響,還是不得而知的。
我們有理由期待,隨著時(shí)間的推移,COM+ 的上下文基礎(chǔ)結(jié)構(gòu)和 Remoting 的上下文基礎(chǔ)結(jié)構(gòu)將越來(lái)越接近。但在現(xiàn)階段,如何做到這一點(diǎn)以及何時(shí)做到這一點(diǎn)還不很清楚。
使用 Remoting 的最佳方法
一直以來(lái),開(kāi)發(fā)和測(cè)試分布式組件不僅項(xiàng)目開(kāi)銷大,而且很令開(kāi)發(fā)人員頭疼。以下指導(dǎo)原則是在實(shí)踐中摸索得到的,來(lái)之不易。
入門
Basic Remoting Task List (英文)一文提供了良好的開(kāi)端,可以對(duì)照此文章檢查在首次設(shè)置 Remoting 時(shí)要執(zhí)行哪些任務(wù),最好在整個(gè)過(guò)程中都將此文章作為參考資料。下面簡(jiǎn)單介紹一下要執(zhí)行的步驟:
主機(jī)任務(wù)
- 設(shè)計(jì)服務(wù),選擇應(yīng)用程序域、激活模式、通道、端口和發(fā)布。
- 實(shí)現(xiàn) Remoting 主機(jī)應(yīng)用程序域(例如 IIS/系統(tǒng)服務(wù))。
- 配置主機(jī)激活、通道和協(xié)議設(shè)置。建議使用配置文件,可以通過(guò)調(diào)用 RemotingConfiguration.Configure 加載。
- 發(fā)布接口,供客戶端使用(有關(guān)詳細(xì)信息,請(qǐng)參閱下文中的“接口發(fā)布選擇”)。
客戶端任務(wù)
- 設(shè)計(jì)客戶端,選擇應(yīng)用程序域和激活模式。
- 考慮是否需要注冊(cè)通道和端口。
- 獲取遠(yuǎn)程類型元數(shù)據(jù)。
- 實(shí)現(xiàn)客戶端應(yīng)用程序域。
- 配置客戶端激活模式和其他類型的信息,如應(yīng)用程序名稱、通道和對(duì)象 URI 等。建議使用配置文件,可以通過(guò)調(diào)用 RemotingConfiguration.Configure 加載。
格式化選擇
作為標(biāo)準(zhǔn),Remoting 可以配置為在 HTTP 通道上使用 SOAP 或二進(jìn)制格式化程序,或者在 TCP 通道上使用二進(jìn)制格式化程序。一般情況下,在客戶端配置文件中輸入適當(dāng)?shù)臈l目和調(diào)用靜態(tài)的 RemotingConfiguration.Configure 方法都可以實(shí)現(xiàn)這種配置。
例如,要將 Remoting 連接配置為使用 HTTP 上的二進(jìn)制格式化程序,可以按以下方法完成配置條目:
<channel ref="http" useDefaultCredentials="true" port="0"> <clientProviders> <formatter ref="binary"/> </clientProviders> </channel>
這里的“channel ref”指 HTTP 協(xié)議,“formatter ref”指要在通道上發(fā)送的消息格式,在此示例中為二進(jìn)制。
遺憾的是,在開(kāi)發(fā)過(guò)程中將二進(jìn)制格式化程序用于 HTTP 通道,會(huì)產(chǎn)生屏蔽服務(wù)器端錯(cuò)誤的副作用,例如,一般的服務(wù)器錯(cuò)誤或訪問(wèn)沖突都會(huì)誤報(bào)給客戶端。這是因?yàn)槭褂枚M(jìn)制格式化程序時(shí),客戶端的 Remoting 組件需要以二進(jìn)制格式返回消息,它無(wú)法正確解釋純文本的錯(cuò)誤結(jié)果,并報(bào)告以下錯(cuò)誤:
mscorlib.dll 中出現(xiàn)無(wú)法處理的異常類型 System.Runtime.Serialization. SerializationException。其他信息:BinaryFormatter 版本不兼容。需要使用 1.0 版。收到的版本為 1008738336.1684104552。
這種錯(cuò)誤大部分“不是”因?yàn)榘姹静患嫒荩且驗(yàn)榭蛻舳藷o(wú)法分析文本格式的錯(cuò)誤響應(yīng)。雖然我們相信這種協(xié)議缺陷能夠在產(chǎn)品的未來(lái)版本中得到解決,但還是強(qiáng)烈建議您在開(kāi)發(fā)過(guò)程中使用 SOAP 格式化程序。證實(shí)之后,可以將此格式化程序切換為二進(jìn)制以增強(qiáng)性能,但應(yīng)該在性能優(yōu)勢(shì)充分且必要的情況下才這樣做。
接口發(fā)布選擇
設(shè)計(jì)并構(gòu)建 Remoting 服務(wù)器之后,應(yīng)將其提供的接口發(fā)布給客戶端使用,以解析編譯時(shí)的引用并允許動(dòng)態(tài)地創(chuàng)建代理對(duì)象。有很多方法可以完成此操作,這里有必要重復(fù)一下。但首先有幾點(diǎn)提示:
- 靜態(tài)字段和方法永遠(yuǎn)都不能進(jìn)行遠(yuǎn)程處理,.NET Remoting 始終處理某些形式的實(shí)例成員。
- 私有方法/類型不能進(jìn)行遠(yuǎn)程處理。
- MarshalByRef 類型是通過(guò)引用進(jìn)行遠(yuǎn)程處理的,可序列化的類型是在客戶端進(jìn)程中復(fù)制值并執(zhí)行代碼。
- 對(duì)象虛擬方法 Equals 、 GetHashCode 和 MemberwiseClone 等在本地執(zhí)行。
了解了這些設(shè)計(jì)中應(yīng)該注意的地方,就可以選擇使用以下方法發(fā)布由 Remoting 服務(wù)器導(dǎo)出的接口:
- 向客戶端提供服務(wù)器端的程序集,以在編譯時(shí)使用。當(dāng)只需要接口而不需要實(shí)現(xiàn)時(shí),不建議也沒(méi)必要使用這種方法。
- 對(duì)于 SOAP/HTTP 客戶端(這里的 Remoting 服務(wù)器的功能是提供 Web 服務(wù),盡管對(duì)這種服務(wù)還有些疑惑),Remoting 服務(wù)器可以提供說(shuō)明服務(wù)器對(duì)象和方法的 Web 服務(wù)說(shuō)明語(yǔ)言 (WSDL) 文件。.NET Framework SDK 附帶的 SOAPSUDS 實(shí)用程序可用于生成這些 WSDL 文件,以作為元數(shù)據(jù)使用。實(shí)際上,這種方法更適合 Web 服務(wù)(從嚴(yán)格的 asmx 意義上講)而不是 Remoting,因?yàn)?Remoting 接口的 WSDL 并不能與 Web 服務(wù)接口的 WSDL 完全兼容。 Soapsuds Tool (英文)上的 .NET Framework Tools 文檔詳細(xì)介紹了 SOAPSUDS 實(shí)用程序。
- 在單獨(dú)的庫(kù)中聲明一個(gè)接口并使用客戶端部署該庫(kù)。發(fā)布執(zhí)行該接口的服務(wù)器類,客戶端將可以使用它,方法是獲取它執(zhí)行的接口的代理。這是一種非常清楚的設(shè)計(jì)選擇,因?yàn)樗侨藗兲貏e感興趣的接口。這種方法只能用于服務(wù)器激活的對(duì)象(請(qǐng)參閱 產(chǎn)品特性 一節(jié)),因?yàn)闊o(wú)法創(chuàng)建接口的實(shí)例。
- 使用 SOAPSUDS 為客戶端構(gòu)建替代類作為元數(shù)據(jù)使用。您可以對(duì) Remoting 服務(wù)器程序集運(yùn)行 SOAPSUDS,生成輸出程序集(可以作為元數(shù)據(jù)直接使用)或源文件(可以直接包括在應(yīng)用程序中)。 這種機(jī)制對(duì)于構(gòu)建多層應(yīng)用程序很有用,在這種應(yīng)用程序中,一層中的對(duì)象要訪問(wèn)另一層中的遠(yuǎn)程對(duì)象。 這種方法很有意思,上文的簡(jiǎn)介部分中引用的多層應(yīng)用程序就使用了此方法。
假設(shè)我們?cè)谝韵挛募A中打開(kāi)一個(gè)命令窗口:
$FRAMEWORKSDK\Samples\Technologies\Remoting\Basic\RemotingHello\Service
我們可以編寫: soapsuds -id:.-types:Hello.HelloService,Hello -oa:HelloInterface.dll
這將創(chuàng)建一個(gè)輸出程序集 HelloInterface.dll,它包含在當(dāng)前目錄的 Hello 程序集中找到的只基于 Remoting 服務(wù)器 Hello.HelloService 的元數(shù)據(jù)。該程序集可由客戶端直接使用。Remoting 服務(wù)器的位置是根據(jù)標(biāo)準(zhǔn)的 Remoting 配置,基于運(yùn)行時(shí)提供的配置數(shù)據(jù)派生得到的。為客戶端程序集生成的 MSIL
ldfld object [System.Runtime.Remoting]System.Runtime.Remoting.Services.RemotingClientProxy::_tp
清楚地顯示出我們沒(méi)有使用 Remoting 服務(wù)器實(shí)現(xiàn),而是使用了由 SOAPSUDS 生成的元數(shù)據(jù)所構(gòu)建的代理類。
不能確保/支持 SOAPSUDS 使用二進(jìn)制進(jìn)行格式化,因?yàn)樗谳敵龀绦蚣獢?shù)據(jù)中嵌入/映射了一些 SOAP 特有的內(nèi)容。
建議您盡量保持 Remoting 接口的簡(jiǎn)單,使用“充實(shí)”而不“花哨”的接口,也就是說(shuō),要試著限制設(shè)計(jì)中遠(yuǎn)程調(diào)用的數(shù)量。在某些情況下,這可能需要傳遞冗余參數(shù)。將遠(yuǎn)程接口放在單獨(dú)的類中,與實(shí)際實(shí)現(xiàn)的類相區(qū)分。這樣可以獲得一種表面類型模式:在需要時(shí),可以輕松地使用另一種技術(shù)替換其中的 Remoting 層。
管理錯(cuò)誤
本節(jié)介紹在開(kāi)發(fā)(和使用)Remoting 解決方案的過(guò)程中可能會(huì)遇到的錯(cuò)誤情況。在任何情況下,都應(yīng)該記住要使用標(biāo)準(zhǔn)的設(shè)備使用和監(jiān)視方法。事件記錄仍是非常有價(jià)值的信息資源,就象網(wǎng)絡(luò)監(jiān)視器工具一樣,網(wǎng)絡(luò)監(jiān)視器可以專門用于詳細(xì)查看客戶端/服務(wù)器的 Remoting 會(huì)話。中間層的 Remoting 服務(wù)器仍可以使用 Visual Studio .NET 提供的標(biāo)準(zhǔn)調(diào)試工具進(jìn)行調(diào)試,例如,對(duì)于由 IIS 集成的 Remoting 服務(wù)器,可以通過(guò)向 ASP.NET 輔助進(jìn)程附加調(diào)試會(huì)話(Visual Studio .Net | Debug [調(diào)試] | Processes [進(jìn)程] | Attach [附加]) 來(lái)設(shè)置斷點(diǎn)(如果資源可用)。但 Remoting 的錯(cuò)誤很獨(dú)特,下面列出了一些。請(qǐng)注意,所有錯(cuò)誤都已使用 .NET Framework SDK 提供的 Basic Remoting Hello Sample 的各版本進(jìn)行了復(fù)現(xiàn),服務(wù)器和客戶端也已在單機(jī)上運(yùn)行。故障現(xiàn)象與在網(wǎng)絡(luò)鏈接上的相同,只是由于 HTTP/TCP 的超時(shí)設(shè)置不同,需要相當(dāng)長(zhǎng)的時(shí)間才能出現(xiàn)錯(cuò)誤。
丟失 MarshalByRef
由于 Remoting 要通過(guò)引用以用于給定的類,該類必須只做一件事,就是繼承 MarshalByRefObject 。假設(shè)開(kāi)發(fā)人員忘記做這項(xiàng)工作,我們將得到一個(gè) System.Runtime.Remoting.RemotingException 類型的異常,說(shuō)明我們有一個(gè)“丟失的 MarshalByReference”.
是否能正確捕獲和處理這個(gè) RemotingException 將取決于程序員。(想想這個(gè)開(kāi)發(fā)人員忘記了他應(yīng)記住的唯一一件事。)
解決方法是:記住繼承 MarshalByRefObject !
眾所周知的服務(wù)器激活的錯(cuò)誤服務(wù)器端點(diǎn)
對(duì)于服務(wù)器激活(請(qǐng)參閱 產(chǎn)品特性 一節(jié)),Remoting 服務(wù)器將其偵聽(tīng)處聲明為端點(diǎn)。該端點(diǎn)一般包括一個(gè)對(duì)象 URI(遠(yuǎn)程對(duì)象的眾所周知名稱),一個(gè)協(xié)議和一個(gè)端口號(hào)。當(dāng)然,所有這些都可能配置錯(cuò)誤。
錯(cuò)誤的 URI
由服務(wù)提供的 Basic Remoting Hello Sample 的 URI 是 HelloService.soap,如相關(guān)的 web.config 文件中所指定:
<configuration> <system.runtime.remoting> <application> <service> <wellknown mode="SingleCall" type="Hello.HelloService, Hello" objectUri="HelloService.soap" /> </service> </application> </system.runtime.remoting> </configuration>
此服務(wù)是 IIS 集成的。IIS 集成要求 URI 帶有后綴 .rem 或 .soap,我們?cè)诜?wù)器上使用 .rope 。在此實(shí)例中,我們將再次收到 RemotingException ,這次顯示的文本是“對(duì)象 </Hello.soap> 在服務(wù)器上已斷開(kāi)或不存在”。
請(qǐng)確保各個(gè) URI 相互匹配!當(dāng) IIS 集成 Remoting 服務(wù)器時(shí),還要確保 URI 以 .rem 或 .soap 結(jié)尾。
不匹配的協(xié)議/端口
為了進(jìn)行此項(xiàng)測(cè)試,我們切換到控制臺(tái)集成的服務(wù)器,以下是該服務(wù)器的配置文件:
<configuration> <system.runtime.remoting> <application name="RemotingHello"> <service> <wellknown mode="SingleCall" type="Hello.HelloService, Hello" objectUri="HelloService.soap" /> </service> <channels> <channel ref="http" port="8000" /> </channels> </application> </system.runtime.remoting> </configuration>
假設(shè)我們要在服務(wù)器端將協(xié)議更改為 TCP,而使客戶端保留 HTTP。
我們將再次收到 RemotingException ,這次的文本是“底層連接已關(guān)閉:接收時(shí)出現(xiàn)意外錯(cuò)誤”。
端口設(shè)置錯(cuò)誤也會(huì)導(dǎo)致上述異常,唯一的不同是這種情況下,要用較長(zhǎng)的時(shí)間才會(huì)出現(xiàn)錯(cuò)誤。服務(wù)器和客戶端之間的端口和協(xié)議必須匹配。
丟失 URI
另一種可能性是遠(yuǎn)程服務(wù)器沒(méi)有運(yùn)行,例如,服務(wù)器由 IIS 集成,而虛擬應(yīng)用程序或相關(guān)的程序集丟失。再次使用 Basic Hello Remoting 服務(wù)器,我們需要虛擬應(yīng)用程序 RemotingHello 能夠運(yùn)行。如果不能運(yùn)行,我們將收到未處理的異常(取決于調(diào)用代碼),但這次的異常將是:“無(wú)法加載類型 clr:Hello.HelloService, Hello”。
在這些情況下,請(qǐng)確保虛擬應(yīng)用程序在運(yùn)行,而且所需的程序集正確地放置在相關(guān)的 bin 子文件夾中。
總而言之,客戶端必須正確地引用服務(wù)器定義的端點(diǎn)以便激活服務(wù)器,這意味著,端口、協(xié)議和 URI 的定義必須相互匹配。這太容易出錯(cuò)了。因此,如果服務(wù)器的位置定義為:
<service> <wellknown mode="SingleCall" type="Hello.HelloService, Hello" objectUri="HelloService.soap" /> </service>
那么,客戶的設(shè)置必須為:
<client url="http://localhost/RemotingHello"> <wellknown type="Hello.HelloService, Hello" url="http://localhost/RemotingHello/HelloService.soap" /> </client>
其中,URL 表示集成 Remoting 服務(wù)的 IIS 虛擬應(yīng)用程序,類型表示類和程序集名稱。
Remoting 和 ASP.NET Web 服務(wù)
IT 設(shè)計(jì)中最好也是最壞的事情就是可以選擇的體系結(jié)構(gòu)組件太多了。Web 服務(wù)和 .NET Remoting 就屬于這種情況,有時(shí)很難決定針對(duì)不同的目的應(yīng)該選用哪種技術(shù)。當(dāng)然,正確的答案是為要解決的問(wèn)題選擇最佳的技術(shù)。不要使用“始終使用 Web 服務(wù)”或“Web 服務(wù)是 Remoting 的子集,因此它就等于所有的 Remoting”等指令性的評(píng)述。本節(jié)將主要介紹這兩種技術(shù),說(shuō)明在特定的情況下,為什么是選擇這一種更有意義而不是另一種。
ASP.NET Web 服務(wù)和 .NET Remoting
讓我們從 Web 服務(wù)的定義開(kāi)始,定義說(shuō) Web 服務(wù)就是可以在 Web 上提供的服務(wù)。這個(gè)定義并不是很有用,我們不妨進(jìn)一步把它提煉成“通過(guò) SOAP 和 HTTP 訪問(wèn)的、可尋址的處理單元,這個(gè)處理單元是用 WSDL 描述的,可以通過(guò) UDDI 發(fā)布。”這個(gè)定義就有用多了,因?yàn)樗?Web 服務(wù)和將 HTML 發(fā)送回瀏覽器的 Web 服務(wù)器區(qū)分開(kāi)了。為了與 .NET Remoting 進(jìn)行比較,我們特別強(qiáng)調(diào)了 Web 服務(wù)的定義,它與可在 Web 上提供的程序化的服務(wù)不同。例如,根據(jù)我們的定義,可以使用 WSDL 從客戶端通過(guò) HTTP 訪問(wèn)的遠(yuǎn)程主機(jī)就是 Web 服務(wù)。鑒于此(并強(qiáng)調(diào) Microsoft ASP.NET Web 服務(wù)實(shí)現(xiàn)),對(duì)于分布式解決方案,在選擇 ASP.NET Web 服務(wù)和 .NET Remoting 的“結(jié)合點(diǎn)”時(shí),應(yīng)該考慮哪些因素呢?
互操作性
一種常見(jiàn)的 Microsoft 理論是:如果需要在不同系統(tǒng)之間進(jìn)行互操作,應(yīng)該選擇使用開(kāi)放標(biāo)準(zhǔn) (SOAP、XML、HTTP) 的 Web 服務(wù)方法,而使用 .NET Remoting 決不是一種交互的解決方案;如果各種系統(tǒng)中的所有組件都是 CLR 托管的,則 .NET Remoting“可能”是正確的選擇。這一原則的適用范圍很廣,但有所區(qū)分還是非常有用的。.NET 遠(yuǎn)程對(duì)象的客戶端應(yīng)該是 .NET 客戶端。如果您的功能必須在 Web(這里的 Web 即 Internet)上通過(guò)松散耦合的 SOAP 客戶端(例如 Unix 進(jìn)程)才能實(shí)現(xiàn),則 Web 服務(wù)將是正確的選擇。當(dāng)然,Intranet 就不受這種限制:所有客戶端都可以是 .NET 客戶端,而且在這種配置中并不排除 .NET Remoting。同樣,對(duì)于應(yīng)用程序的中間層在防火墻之后并與 Web 層直接通信的環(huán)境,仍可選擇 .NET Remoting。
強(qiáng)大的類型支持
.Net Remoting 支持所有托管的類型、類、接口、枚舉、對(duì)象等,這通常被稱為“多類型保真”。這里的關(guān)鍵在于,如果客戶端和服務(wù)器組件都是在應(yīng)用程序域中運(yùn)行的 CLR 托管的對(duì)象,則數(shù)據(jù)類型的互操作是不成問(wèn)題的。從根本上講,我們擁有的是一個(gè)封閉的系統(tǒng),會(huì)話的兩端可以完全被理解,因此我們可以充分利用這一事實(shí),處理好用于通信的數(shù)據(jù)類型和對(duì)象。
在各種系統(tǒng)并存的情況下,我們需要考慮系統(tǒng)之間的互操作性。對(duì)于可互操作的數(shù)據(jù)類型,我們要謹(jǐn)慎處理。例如,Web 服務(wù)數(shù)據(jù)類型的定義要基于 XML 架構(gòu)定義 (XSD) 關(guān)于數(shù)據(jù)類型的說(shuō)明。任何可以使用 XSD 進(jìn)行描述并可以在 SOAP 上進(jìn)行互操作的類型都可以使用。但是,這也確實(shí)使得某些數(shù)據(jù)類型不能使用。例如,對(duì)于無(wú)符號(hào)的字符類型或枚舉,不存在相應(yīng)的 W3C XSD 表示法。對(duì)于不同的 Web 服務(wù)實(shí)現(xiàn),集合的處理不同,異常和數(shù)據(jù)集的處理也不同。另一個(gè)問(wèn)題是,私有字段和屬性不在 Web 服務(wù)調(diào)用之間傳遞,這對(duì)字段和屬性本身來(lái)說(shuō)并不是關(guān)鍵問(wèn)題,但如果您的系統(tǒng)要求在不同的技術(shù)之間進(jìn)行互操作,則在設(shè)計(jì)和測(cè)試系統(tǒng)時(shí),這卻是一個(gè)要考慮的因素,因?yàn)榭梢园l(fā)送內(nèi)容并不意味著可以接收到它。
再重復(fù)一遍,如果需要在不同的系統(tǒng)之間進(jìn)行互操作,就不應(yīng)該考慮使用 .NET Remoting 技術(shù)。如果是封閉的、CLR 托管的解決方案,則可以使用它。
狀態(tài)管理
我們已經(jīng)看到很多方法,使用基于激活方式(客戶端激活或 Singleton)的 .Net Remoting 實(shí)現(xiàn)狀態(tài)管理。對(duì) .NET Remoting 和 Web 服務(wù)來(lái)說(shuō),通過(guò) HTTP(帶有不確定超時(shí)的無(wú)狀態(tài)協(xié)議)來(lái)管理每個(gè)客戶端的連接狀態(tài)是件煩瑣且不切實(shí)際的事情。但是,如果您需要維護(hù)狀態(tài),那么 Remoting 提供了一種基于每個(gè)對(duì)象的解決方案。Web 服務(wù)沒(méi)有提供這種每個(gè)客戶端的連接狀態(tài)管理,但提供了對(duì) ASP.NET 會(huì)話和應(yīng)用程序?qū)ο蟮脑L問(wèn)。
生存期管理
與狀態(tài)管理有關(guān)的是生存期管理。正如我們所看到的,Remoting 為管理遠(yuǎn)程對(duì)象的生存期提供了功能強(qiáng)大的機(jī)制。Web 服務(wù)對(duì)象隨 Web 服務(wù)的調(diào)用而存在和消失(從概念上講,對(duì)同步和異步都是這樣)。在這方面,Web 服務(wù)與 Remoting 相比,是一種單一調(diào)用類型。Remoting 對(duì)遠(yuǎn)程對(duì)象的激活和終止提供了更大程度上的控制。這對(duì)于您的設(shè)計(jì)可能有意義,也可能沒(méi)意義。
按值調(diào)用和按引用調(diào)用
傳遞到 Web 服務(wù)調(diào)用的對(duì)象是經(jīng)過(guò)序列化的,并按值進(jìn)行傳遞。傳遞到 Remoting 的對(duì)象或被調(diào)用的對(duì)象本身可以按值或按引用進(jìn)行傳遞。序列化的遠(yuǎn)程對(duì)象方法是在客戶端進(jìn)行處理的。在 Remoting 和 Web 服務(wù)之間進(jìn)行選擇時(shí)應(yīng)該考慮這些不同。當(dāng)然,這些考慮對(duì)您來(lái)說(shuō)是否重要,也取決于要解決的問(wèn)題的性質(zhì)。
支持的協(xié)議
Web 服務(wù)調(diào)用僅限于 HTTP 上的 SOAP 編碼的 XML。Remoting 可以使用 TCP 傳輸,或者擴(kuò)展基礎(chǔ)結(jié)構(gòu)以支持自定義的協(xié)議。例如,在 www.gotdotnet.com 上的 jhawk 用戶示例部分提供了一個(gè)使用 Named Pipe 的 Remoting 實(shí)現(xiàn)。
這里是 NamedPipe 自述文件的一個(gè)片段,闡明了 Remoting 的可擴(kuò)展性:
通過(guò)實(shí)現(xiàn) IChannel* 接口,可以使用可插入式通道結(jié)構(gòu)將通道插入到 .NET Remoting 中。
Named Pipe 通道支持以下功能:
* 通過(guò)命名管道進(jìn)行通信
* 同步消息
* 異步消息
* 單程消息
* 回調(diào)
* 通道接收
* 通道屬性
* 自動(dòng)生成管道名稱
因此,如果您需要 Named Pipe,Remoting 可以提供解決方案。但是,與 SSPI NTLM 身份驗(yàn)證解決方案一樣,Microsoft 目前也不支持這種解決方案,也許將來(lái) Microsoft 會(huì)滿足這種需要。
性能
如果性能對(duì)您的設(shè)計(jì)確實(shí)至關(guān)重要,那么通過(guò) TCP 使用二進(jìn)制消息格式的 Remoting 確實(shí)提供了一些顯著的性能優(yōu)勢(shì)。對(duì)于本文所介紹的結(jié)果,如果要完整了解產(chǎn)生此結(jié)果的測(cè)試環(huán)境和測(cè)試,請(qǐng)參閱 性能比較:.NET Remoting 與 ASP.NET Web 服務(wù) 一文。
這里是從這篇文章中總結(jié)出的一些性能統(tǒng)計(jì):
圖例:ASMX - Web 服務(wù),其他都是 Remoting 解決方案
WS 表示集成遠(yuǎn)程組件的 Windows 服務(wù)。
圖 1:性能統(tǒng)計(jì)
文章接下來(lái)對(duì)性能圖表進(jìn)行了解釋,如下所述:
“如上所示,對(duì)于 WS_TCP_Binary,其中的對(duì)象被配置為使用 TCP 通道和 Binary 格式化程序,而主機(jī)是 Windows 服務(wù),其性能要優(yōu)于其他的分布式技術(shù)。這是因?yàn)樵摲椒ㄍㄟ^(guò)原始 TCP 套接字傳輸二進(jìn)制數(shù)據(jù)(比 HTTP 的效率高),且數(shù)據(jù)不需要編碼/解碼,因而降低了系統(tǒng)開(kāi)銷。可以看到,WS_TCP_Binary 和最慢的方法之間存在約 60% 的性能差距。
雖然 IIS_HTTP_Binary 與 WS_HTTP_Binary 產(chǎn)生的二進(jìn)制負(fù)載相同,但其速度較慢,原因是從 IIS (Inetinfo.exe) 到 Aspnet_wp.exe 之間有額外的進(jìn)程躍點(diǎn)。IIS_HTTP_SOAP 與 WS_HTTP_SOAP 的性能差別也是由此造成的。
WS_HTTP_Binary 和 WS_TCP_SOAP 的性能幾乎相同。盡管前者有 HTTP 分析方面的額外系統(tǒng)開(kāi)銷,后者有 SOAP 分析方面的額外系統(tǒng)開(kāi)銷,但在本例中 HTTP 分析的系統(tǒng)開(kāi)銷與 SOAP 分析的系統(tǒng)開(kāi)銷幾乎相同。
ASP.NET Web 服務(wù)的性能優(yōu)于 IIS_HTTP_SOAP 和 WS_HTTP_SOAP,因?yàn)?ASP.NET XML 序列化比 .NET Remoting SOAP 序列化的效率高。從上述內(nèi)容可以看出,ASP.NET Web 服務(wù)與 IIS_HTTP_Binary 的性能幾乎相同。”
如果原始速度確實(shí)非常重要,那么這“60% 性能差距”就很有意義了。其缺點(diǎn)是要將服務(wù)器集成在 Windows 服務(wù)中,以便使用 TCP 協(xié)議(請(qǐng)參閱前面的 遠(yuǎn)程集成 一節(jié))。它有效地權(quán)衡了性能的安全性,而且是一種“最好不要用于 Internet 或不安全的 Intranet”的方法。
小結(jié)
ASP.NET Web 服務(wù)基于 XML,用于要求使用 HTTP(假定它們集成在 IIS)的實(shí)際應(yīng)用中,能夠提供簡(jiǎn)單的編程模式和強(qiáng)大的跨平臺(tái)支持,它通過(guò)使用 SoapExtensions 提供了一定程度的擴(kuò)展性,例如加密數(shù)據(jù)流。Remoting 的編程模式更為復(fù)雜,但就協(xié)議和消息格式而言,它在類型保真、狀態(tài)管理和擴(kuò)展性方面具有明顯的優(yōu)勢(shì)。Remoting 不能用于非 .NET 客戶端,因此無(wú)法實(shí)現(xiàn) Internet 客戶端與遠(yuǎn)程主機(jī)的直接連接。當(dāng)在 IIS 之外集成時(shí),Remoting 不能提供安全性模型。當(dāng)集成在 IIS 時(shí),Remoting 可以提供與 ASP.NET 相同的安全性功能,包括使用 SSL 等安全協(xié)議。如果不需要考慮與其他平臺(tái)的互操作性,而且客戶端和服務(wù)器的配置完全在您的控制之下,則可以考慮使用 .NET Remoting。使用 Remoting 時(shí),使用了 HTTP 通道的 IIS 集成要優(yōu)于非 IIS 集成,這樣,可以得益于相關(guān)的安全性和伸縮性基礎(chǔ)結(jié)構(gòu)。當(dāng)然,這意味著您必須能夠在解決方案中與 IIS 進(jìn)行互操作。如果這無(wú)法實(shí)現(xiàn),那么使用 Remoting“可能”就是件無(wú)法實(shí)現(xiàn)的艱巨任務(wù)了,這與要解決的問(wèn)題的性質(zhì)有關(guān)。由于 .NET Remoting 要求使用 .NET 客戶端,因此有必要使用最快的可用格式化程序,這樣一來(lái),選擇二進(jìn)制而不選擇 SOAP 將產(chǎn)生更好的性能。請(qǐng)記住上文的 最佳方法 一節(jié)的建議,在發(fā)布時(shí)使用此格式化程序,而不要在開(kāi)發(fā)過(guò)程中使用。
摘要
.NET Remoting 是在某些分布式解決方案中使用的有效工具,它在所支持的協(xié)議和消息格式方面提供了可擴(kuò)展的模型,并能在特定的情況下提供性能優(yōu)勢(shì)。它不應(yīng)直接部署在 Internet 上,而且它的服務(wù)器對(duì)象應(yīng)該集成在 IIS 之下,以充分利用 IIS 為在其控制下運(yùn)行的進(jìn)程提供的安全性和性能特性。
對(duì)于“封閉”的分布式解決方案,其中的客戶端和服務(wù)器都是 CLR 托管的進(jìn)程,應(yīng)該考慮使用 Remoting。例如,Intranet 解決方案中使用安全 TCP 通道(如 IPSec)或 HTTP 的任意層中的組件,或者通過(guò)防火墻與 .NET Web 層組件會(huì)話的中間層應(yīng)用程序組件。在這種情況下,當(dāng)證實(shí)應(yīng)用程序使用 SOAP 格式化程序后,應(yīng)該選擇二進(jìn)制格式化程序和 HTTP 通道。
對(duì)于要與非 CLR 客戶端進(jìn)行互操作的系統(tǒng),請(qǐng)使用 ASMX Web 服務(wù),但要謹(jǐn)慎處理某些數(shù)據(jù)類型(請(qǐng)參閱 強(qiáng)大的類型支持 一節(jié))。
請(qǐng)注意,使用 TCP 在 IIS 之外集成會(huì)帶來(lái)性能優(yōu)勢(shì),但需要自定義的安全性。
設(shè)計(jì)與實(shí)現(xiàn)
實(shí)現(xiàn)和配置 Remoting 是一個(gè)相當(dāng)容易的過(guò)程。在此過(guò)程中,首先要選擇 Remoting 主機(jī)、協(xié)議和激活模式。請(qǐng)盡量簡(jiǎn)化設(shè)計(jì)和實(shí)現(xiàn)過(guò)程,并認(rèn)真考慮哪種接口發(fā)布機(jī)制對(duì)您的解決方案最有意義。建議的方法是,只把接口作為最易懂的概念模型來(lái)發(fā)布,但這樣一來(lái)就不能使用客戶端激活的對(duì)象。調(diào)試程序、事件日志和網(wǎng)絡(luò)監(jiān)視是開(kāi)發(fā)過(guò)程中非常有用的工具,在開(kāi)發(fā)遠(yuǎn)程組件時(shí),它們也能助您一臂之力。
Remoting 的未來(lái)
象“何時(shí)使用 Remoting、何時(shí)使用 Web 服務(wù)”等問(wèn)題都是很難回答的問(wèn)題,更何況術(shù)語(yǔ)的定義也不是很清楚。例如,如果 Web 服務(wù)的定義不清楚,Remoting 就有可能配置為 Web 服務(wù)。
或許將來(lái) Remoting 和 ASMX 技術(shù)能逐步融合。但在目前,我們至少可以比較合理地說(shuō)明何時(shí)使用哪種技術(shù),如上所述。
當(dāng)前的開(kāi)發(fā)重點(diǎn)是提供路由、安全性和事務(wù)支持的 GXA 實(shí)現(xiàn)。這種實(shí)現(xiàn)要基于使用 SOAP 標(biāo)頭,而目前的直接目標(biāo)是擴(kuò)展 Web 服務(wù)的功能。雖然如本文所述,從傳統(tǒng)意義上講,GXA 不支持 .NET Remoting,但它支持 Remoting 解決的很多問(wèn)題,如狀態(tài)和事務(wù)管理等。雖然現(xiàn)在的 GXA 實(shí)現(xiàn)可以解決 Web 服務(wù)所面對(duì)的許多問(wèn)題,但它最根本的目的是盡量以不需要太高技術(shù)含量的方式解決這些問(wèn)題。看到 GXA 的開(kāi)發(fā)對(duì) Web 服務(wù)和 .Net Remoting 的影響,將是一件充滿樂(lè)趣的事情。
其他資源
- Accessing Objects in Other Application Domains using .NET Remoting (英文)
- Microsoft PAG Building Secure ASP.NET Applications, Chapter 11:Remoting Security (英文)
- Enterprise:Remoting reading list (英文)
- ASP.NET Web 服務(wù)還是 .NET Remoting:如何選擇
適用于:
Microsoft? .NET Framework
Microsoft? .NET Remoting
摘要: 本文適用于要將 .NET Remoting 用于分布式多層應(yīng)用程序設(shè)計(jì)的人員。文章從開(kāi)發(fā)人員的角度介紹了該技術(shù)的功能。開(kāi)發(fā)人員曾得益于這項(xiàng)技術(shù)所提供的方便的 RPC 機(jī)制,也曾感受過(guò)其不足之處帶來(lái)的不便。本文假設(shè)讀者熟悉 .NET Remoting,即使沒(méi)有實(shí)際使用過(guò),至少對(duì)其概念也有所了解。
產(chǎn)品特性 一節(jié)對(duì)使用 Remoting 進(jìn)行設(shè)計(jì)的人員很有用, 最佳方法 一節(jié)適用于使用 Remoting 進(jìn)行構(gòu)建的人員, Remoting 和 Web 服務(wù) 一節(jié)試圖消除有關(guān)“在何時(shí)選用何種技術(shù)”的困惑, 摘要 是對(duì)內(nèi)容的精煉。
目錄
概述
.NET Remoting 被譽(yù)為管理應(yīng)用程序域之間的 RPC 的首選技術(shù)。應(yīng)用程序域是公共語(yǔ)言運(yùn)行庫(kù)的隔離單元,它們是在進(jìn)程內(nèi)創(chuàng)建并運(yùn)行的。這與 CLR 和非 CLR 托管的進(jìn)程之間的進(jìn)程間通信(互操作)不同。后一種類型的 RPC 通信(特別是 Web 上的)一般被認(rèn)為是 Web 服務(wù)領(lǐng)域的問(wèn)題。遺憾的是,這種看似清楚的區(qū)分,卻由于可以在 IIS 下集成 .Net Remoting 服務(wù)器而變得模糊,正如 Microsoft .NET Remoting 框架簡(jiǎn)介 一文中所述:
“通過(guò)在 IIS 中集成 .NET Remoting 對(duì)象,可以將其作為一種 Web 服務(wù)提供……”
一些 Microsoft 客戶可能對(duì) .NET Remoting 或多或少有些疑惑。我經(jīng)常聽(tīng)到有人問(wèn)“應(yīng)該在什么時(shí)候使用 Remoting?”、“Remoting 何時(shí)會(huì)支持 NTLM?”、“如何保證遠(yuǎn)程會(huì)話的安全?”、“COM+ 怎么樣?”以及“Remoting 如何管理事務(wù)?”
除了回答這些問(wèn)題,本文還將介紹一些使用 .NET Remoting 的最佳方法,并概要介紹當(dāng)前可以獲得的功能。 摘要 預(yù)測(cè)了該技術(shù)的未來(lái)發(fā)展方向,特別是有關(guān) Web 服務(wù)和新興的全局 XML Web Service 體系結(jié)構(gòu) (GXA) 規(guī)范的問(wèn)題。
產(chǎn)品特性 一節(jié)的信息大部分來(lái)自 TechED N.Z. 2002,這次演示重點(diǎn)介紹了在分布式解決方案中使用 Remoting 的不同方法,闡明了 Remoting 的優(yōu)點(diǎn),也提到了一些不足之處。
最佳方法 一節(jié)源于在多層 .NET 應(yīng)用程序中使用 Remoting 的個(gè)人經(jīng)驗(yàn),其中介紹了很多在開(kāi)發(fā)過(guò)程中用到的簡(jiǎn)單易行的最佳方法。
某些節(jié)包括了根據(jù)非正式談話整理得到的資料,談話的對(duì)象是對(duì)該技術(shù)及其發(fā)展方向都有深刻理解的 Microsoft 內(nèi)部人員,但這里提供的信息決不代表未來(lái)的產(chǎn)品發(fā)布計(jì)劃或安排。
產(chǎn)品特性
本節(jié)介紹 .NET Remoting 的功能和產(chǎn)品特性。
客戶端/服務(wù)器通信
.NET Remoting 提供了一種很有用的方法,用于管理跨應(yīng)用程序域的同步和異步 RPC 會(huì)話。遠(yuǎn)程對(duì)象代碼可以運(yùn)行在服務(wù)器上(如服務(wù)器激活的對(duì)象和客戶端激活的對(duì)象),也可以運(yùn)行在客戶端上(其上的遠(yuǎn)程對(duì)象已經(jīng)通過(guò)客戶端/服務(wù)器的連接進(jìn)行了序列化)。在任何一種情況下,只要完成初始化和配置(這并不困難),即可使用非常簡(jiǎn)單的編程語(yǔ)言,只需要少量的代碼。遠(yuǎn)程對(duì)象(在按引用封送時(shí)是代理的對(duì)象)的使用對(duì)程序員是透明的。例如,早期的 Windows RPC 機(jī)制要求熟悉的類型和使用 IDL 工具的封送處理知識(shí),并向開(kāi)發(fā)人員公開(kāi) RPC 客戶端和服務(wù)器存根的管理。Remoting 在為 .NET 提供 RPC 時(shí)要容易得多,而且由于使用簡(jiǎn)單易懂的 .NET 數(shù)據(jù)類型,從而消除了早期 RPC 機(jī)制中存在的類型不匹配的情況(這是一個(gè)非常大的威脅)。
默認(rèn)情況下,可以將 Remoting 配置為使用 HTTP 或 TCP 協(xié)議,并使用 XML 編碼的 SOAP 或本機(jī)二進(jìn)制消息格式進(jìn)行
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061

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