淺談.net remoting 與webservice


1. .NET Remoting

  .NET Remoting是微軟隨.NET推出的一種分布式應用解決方案,被譽為管理應用程序域之間的 RPC 的首選技,它允許不同應用程序域之間進行通信(這里的通信可以是在同一個進程中進行、一個系統的不同進程間進行、不同系統的進程間進行)。

  更具體的說,Microsoft .NET Remoting 提供了一種允許對象通過應用程序域與另一對象進行交互的框架。也就是說,使用.NET Remoting,一個程序域可以訪問另外一個程序域中的對象,就好像這個對象位於自身內部,只不過,對這個遠程對象的調用,其代碼是在遠程應用程序域中進行的,例如在本地應用程序域中調用遠程對象上一個會彈出對話框的方法,那么,這個對話框,則會在遠程應用程序域中彈出。

.NET Remoting框架提供了多種服務,包括激活和生存期支持,以及負責與遠程應用程序進行消息傳輸的通訊通道。格式化程序用於在消息通過通道傳輸之前,對其進行編碼和解碼。應用程序可以在注重性能的場合使用二進制編碼,在需要與其他遠程處理框架進行交互的場合使用 XML 編碼。在從一個應用程序域向另一個應用程序域傳輸消息時,所有的 XML 編碼都使用 SOAP 協議。出於安全性方面的考慮,遠程處理提供了大量掛鈎,使得在消息流通過通道進行傳輸之前,安全接收器能夠訪問消息和序列化流。

.NET Remoting協同工作能力 

 下圖是.NET Remoting的體系結構圖 

                .NET Remoting通信體系結構 

一般來說,.NET Remoting包括如下幾點主要元素: 

Ø       遠程對象:運行在Remoting服務器上的對象。客戶端通過代理對象來間接調用該對象的服務,如上圖的“通信體系結構”所示。在.NET Remoting體系中,要想成為遠程對象提供服務,該對象的類必須是MarshByRefObject的派生對象。另外,要說明的是,需要在網絡上傳遞的對象,例如“參數”,則必須是可序列化的。 

Ø 信道:信道是服務器和客戶機進行通信用的(這里的服務器和客戶機並不一定都是計算機,也可能是進程)。在.NET Remoting中,提供了三種信道類型:TCPHTTPIPC,另外,也可以定制不同的信道以適應不同的通信協議。 

Ø      消息:客戶機和服務器通過消息進行信息交換,消息在信道中傳遞。這里的消息包括,遠程對象的信息,調用方法名稱,參數,返回值等。 

Ø       格式標識符:該標識符標明了消息是按照什么樣的格式被發送到信道上的,目前.NET 2.0提供了兩種格式標識符:SOAP格式和二進制格式。SOAP格式標識符符合SOAP標准,比較通用,可以和非.NET 框架的Web服務通信。二進制格式標識符,則在速度、效率上面更生一籌,但通用性較SOAP差。另外,Remoting還支持自定義的格式標識符。(順便說一下:TCP信道,默認使用二進制格式傳輸,因為這個效率更高;Http信道則默認使用SOAP格式;不過在系統中,哪種信道具體使用哪種格式,則是可以根據需要設置的。)。 

Ø       格式標識符提供程序:它用於把格式標識符和信道聯系起來。在創建信道時,可以指定所要使用的標識符提供程序,一旦指定了提供程序,那么消息被發送到信道上的格式也就確定了下來。  

為序列化消息, .NET Remoting 提供了兩類格式程序接收器: BinaryFormatterSoapFormatter。選擇的類型很大程度上取決於連接分布式對象的網絡環境的類型。由於. NET  Remoting體系結構的可插入特性,可以創建自己的格式程序接收器,並插入到.NET Remoting基礎設施中。這種靈活性使基礎設施能夠支持可能的各種線路格式。 

對於可以發送並接收二進制數據(例如TCP/IP)的網絡傳輸協議,可以使用System.Runtime.Serialization.Formatters.Binary名字空間中定義的BinaryFormatter類型。顧名思義,BinaryFormatter將消息對象序列化為一個二進制格式的流。這是消息對象在線纜間進行傳輸的最有效而簡潔的表示方式。一些網絡傳輸系統不允許發送和接收二進制數據。這類傳輸迫使應用程序在發送之前將所有的二進制數據轉換成ASCII文本表示形式。在這種情況下(或者要得到最佳協作能力的時候),.NET RemotingSystem.Runtime.Serialization.Formatters.Soap名字空間中提供SoapFormatter類型。SoapFormatter使用消息的SOAP表示形式將消息序列化為流。 

Ø       代理對象:前面也說過,客戶端不能直接調用遠程對象,客戶機只能通過代理對象來操作遠程對象。代理對象,又分為透明代理和真實代理。在客戶機看來,代理對象和遠程對象是一樣的。客戶機調用透明代理對象上的方法,透明代理再調用真實代理上的Invoke方法,Invoke方法再使用消息接受器把消息傳遞到信道上。 

下圖是客戶機的方法調用導致消息在信道間傳遞的一個體系結構圖: 

              消息在信道上的傳遞過程 

Ø       消息接受器:如上圖所示,消息接受器在服務器端和客戶端都有,接受真實代理的調用,把序列化的消息發布到信道上。 

Ø       激活器:這涉及到對象生命期管理,客戶機使用激活器在服務器上創建遠程對象,或者說是申請一個遠程對象的引用。 

Ø       RemotingConfiguration類:該類用於配置遠程服務器和客戶機的一個實用類,它可以用於讀取配置文件或者動態地配置遠程對象。說明一點的是:RemotingConfiguration類中的大部分屬性、方法都是靜態的,這就意味着很多屬性,如應用程序名稱,只能通過當前屬性或配置文件設置一次。如果應用程序運行在宿主環境中,例如 Internet 信息服務 (IIS),則可能已經設置了該值(通常將其設置為虛擬目錄)。如果未設置應用程序名稱,則當前屬性將返回空引用。 

Ø       ChannelServices類:該類用於注冊信道,並把消息分派到信道上。

 

 

下面寫一個.NET Remoting 的示例程序,示例工程的結構如下:

 其中,ClassLibrary是遠程對象的類庫,Client、Server是控制台程序。

ClassLibrary代碼如下:

using System;

namespace ClassLibrary1
{
    public class Class1:MarshalByRefObject
    {
         public Class1()
            : base()
        {
            Console.WriteLine("遠程對象被創建!");
        }

         ~Class1()
        {
            Console.WriteLine("遠程對象被析構!");
        }

        public void SayHello(string name)
        {
            Console.WriteLine("你好,{0}", name);
        }

        public int GetSomthing(string s)
        {
            if (s!=null)
            { 
                Console.WriteLine("我執行了!");
                return s.Length;
            }
            return -1;           
        }

    }
}

相關說明如下:

1.遠程對象的創建

  客戶端在獲取服務器端對象時,並不是獲得實際的服務端對象,而是獲得它的引用。因此在Remoting中,對於遠程對象有一些必須的定義規范要遵循。

  由於Remoting傳遞的對象是以引用的方式,因此所傳遞的遠程對象類必須繼承MarshalByRefObject。MSDN對MarshalByRefObject的說明是:MarshalByRefObject 是那些通過使用代理交換消息來跨越應用程序域邊界進行通信的對象的基類。不是從 MarshalByRefObject 繼承的對象會以隱式方式按值封送。當遠程應用程序引用一個按值封送的對象時,將跨越遠程處理邊界傳遞該對象的副本。因為您希望使用代理方法而不是副本方法進行通信,因此需要繼承MarshallByRefObject。

  需要注意的是Class1繼承自MarshalByRefObject類,即聲明為遠程對象。關於MarshalByRefObject具體請參考MSDN。

Server的代碼如下:

using System;
using System.Runtime.Remoting.Channels.Tcp;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting;
using ClassLibrary1;

namespace Server
{
    class Program
    {
        /// <summary>
        /// 服務端應用
        /// </summary>
        /// <param name="args"></param>
        static void Main(string[] args)
        {
            //利用TCP通道,並偵聽12345端口
            TcpServerChannel channel = new TcpServerChannel(12345);
            ChannelServices.RegisterChannel(channel, true);
            //使用WellKnown激活方式,並且使用SingleCall模式
            RemotingConfiguration.RegisterWellKnownServiceType(typeof(Class1), "Class1", WellKnownObjectMode.SingleCall);
            Console.Read();
        }
    }
}

 相關說明如下:

1、Remoting的兩種通道

  Remoting的通道主要有三種:Tcp和Http和IPC。在.Net中,System.Runtime.Remoting.Channel中定義了IChannel接口。IChannel接口包括了TcpChannel通道類型和Http通道類型。它們分別對應Remoting通道的前兩種類型。

  TcpChannel類型放在名字空間System.Runtime.Remoting.Channel.Tcp中。Tcp通道提供了基於Socket的傳輸工具,使用Tcp協議來跨越Remoting邊界傳輸序列化的消息流。TcpChannel類型默認使用二進制格式序列化消息對象,因此它具有更高的傳輸性能。HttpChannel類型放在名字空間    System.Runtime.Remoting.Channel.Http中。它提供了一種使用Http協議,使其能在Internet上穿越防火牆傳輸序列化消息流。默認情況下,  HttpChannel類型使用Soap格式序列化消息對象,因此它具有更好的互操作性。IPC不需要通道,適合本機使用,速度可想而知,比Tcp和Http都要快。

  通常在局域網內,我們更多地使用TcpChannel;如果要穿越防火牆,則使用HttpChannel。服務端和客戶端在同一台主機上,優先考慮IPC。

2、遠程對象的激活方式

  在訪問遠程類型的一個對象實例之前,必須通過一個名為Activation的進程創建它並進行初始化。這種客戶端通過通道來創建遠程對象,稱為對象的激活。在Remoting中,遠程對象的激活分為兩大類:服務器端激活和客戶端激活。

  (1)服務器端激活,又叫做WellKnow方式,很多又翻譯為知名對象。為什么稱為知名對象激活模式呢?是因為服務器應用程序在激活對象實例之前會在一個眾所周知的統一資源標識符(URI)上來發布這個類型。然后該服務器進程會為此類型配置一個WellKnown對象,並根據指定的端口或地址來發布對象。.Net Remoting把服務器端激活又分為SingleTon模式和SingleCall模式兩種。

  SingleTon模式:此為有狀態模式。如果設置為SingleTon激活方式,則Remoting將為所有客戶端建立同一個對象實例。當對象處於活動狀態時,SingleTon實例會處理所有后來的客戶端訪問請求,而不管它們是同一個客戶端,還是其他客戶端。SingleTon實例將在方法調用中一直維持其狀態。舉例來說,如果一個遠程對象有一個累加方法(i=0;++i),被多個客戶端(例如兩個)調用。如果設置為SingleTon方式,則第一個客戶獲得值為1,第二個客戶獲得值為2,因為他們獲得的對象實例是相同的。如果熟悉Asp.Net的狀態管理,我們可以認為它是一種Application狀態。

  SingleCall模式:SingleCall是一種無狀態模式。一旦設置為SingleCall模式,則當客戶端調用遠程對象的方法時,Remoting會為每一個客戶端建立一個遠程對象實例,至於對象實例的銷毀則是由GC自動管理的。同上一個例子而言,則訪問遠程對象的兩個客戶獲得的都是1。我們仍然可以借鑒Asp.Net的狀態管理,認為它是一種Session狀態。

  (2)客戶端激活。與WellKnown模式不同,Remoting在激活每個對象實例的時候,會給每個客戶端激活的類型指派一個URI。客戶端激活模式一旦獲得客戶端的請求,將為每一個客戶端都建立一個實例引用。SingleCall模式和客戶端激活模式是有區別的:首先,對象實例創建的時間不一樣。客戶端激活方式是客戶一旦發出調用的請求,就實例化;而SingleCall則是要等到調用對象方法時再創建。其次,SingleCall模式激活的對象是無狀態的,對象生命期的管理是由GC管理的,而客戶端激活的對象則有狀態,其生命周期可自定義。其三,兩種激活模式在服務器端和客戶端實現的方法不一樣。尤其是在客戶端,SingleCall模式是由GetObject()來激活,它調用對象默認的構造函數。而客戶端激活模式,則通過CreateInstance()來激活,它可以傳遞參數,所以可以調用自定義的構造函數來創建實例。

 Client的代碼如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.Remoting.Channels.Tcp;
using System.Runtime.Remoting.Channels;
using ClassLibrary1;

namespace Client
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                //使用TCP通道連接
                TcpClientChannel channel = new TcpClientChannel();
                ChannelServices.RegisterChannel(channel, true);
                //獲取遠程對象
                Class1 class1 = (Class1)Activator.GetObject(typeof(Class1), "tcp://localhost:12345/Class1");
                //調用遠程對象的方法
                class1.SayHello("DebugLZQ");
                class1.SayHello("http://www.cnblogs.com/DebugLZQ");

                int i=class1.GetSomthing("DebugLZQ");
                Console.WriteLine("輸入的長度是,{0}", i);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message );
            }
            Console.Read();
        }
    }
}

程序的運行結果如下:
Server端運行結果

Client端運行結果:

小結Microsoft .NET Remoting 提供了一種允許對象通過應用程序域與另一對象進行交互的框架。也就是說,使用.NET Remoting,一個程序域可以訪問另外一個程序域中的對象,就好像這個對象位於自身內部,只不過,對這個遠程對象的調用,其代碼是在遠程應用程序域中進行的,例如在本地應用程序域中調用遠程對象上一個會彈出對話框的方法,那么,這個對話框,則會在遠程應用程序域中彈出。

  2.Web Service

 Web Service也叫XML Web Service。 Web Service是一種可以接收從Internet或者Intranet上的其它系統中傳遞過來的請求,輕量級的獨立的通訊技術。是通過SOAP在Web上提供的軟件服務,使用WSDL文件進行說明,並通過UDDI進行注冊。

   XML:(Extensible Markup Language)擴展型可標記語言。面向短期的臨時數據處理、面向萬維網絡,是Soap的基礎。

   Soap:(Simple Object Access Protocol)簡單對象存取協議。是XML Web Service 的通信協議。當用戶通過UDDI找到你的WSDL描述文檔后,他通過可以SOAP調用你建立的Web服務中的一個或多個操作。SOAP是XML文檔形式的調用方法的規范,它可以支持不同的底層接口,像HTTP(S)或者SMTP。

   WSDL:(Web Services Description Language) WSDL 文件是一個 XML 文檔,用於說明一組 SOAP 消息以及如何交換這些消息。大多數情況下由軟件自動生成和使用。

   UDDI (Universal Description, Discovery, and Integration) 是一個主要針對Web服務供應商和使用者的新項目。在用戶能夠調用Web服務之前,必須確定這個服務內包含哪些商務方法,找到被調用的接口定義,還要在服務端來編制軟件,UDDI是一種根據描述文檔來引導系統查找相應服務的機制。UDDI利用SOAP消息機制(標准的XML/HTTP)來發布,編輯,瀏覽以及查找注冊信息。它采用XML格式來封裝各種不同類型的數據,並且發送到注冊中心或者由注冊中心來返回需要的數據。

  Web Service的主要目標是跨平台的可互操作性。為了實現這一目標,Web Service 完全基於XML(可擴展標記語言)、XSD(XML Schema)等獨立於平台、獨立於軟件供應商的標准,是創建可互操作的、分布式應用程序的新平台。因此使用Web Service有許多優點:

  1、跨防火牆的通信

  如果應用程序有成千上萬的用戶,而且分布在世界各地,那么客戶端和服務器之間的通信將是一個棘手的問題。因為客戶端和服務器之間通常會有防火牆或者代理服務器。傳統的做法是,選擇用瀏覽器作為客戶端,寫下一大堆ASP頁面,把應用程序的中間層暴露給最終用戶。這樣做的結果是開發難度大,程序很難維護。 要是客戶端代碼不再如此依賴於HTML表單,客戶端的編程就簡單多了。如果中間層組件換成Web Service的話,就可以從用戶界面直接調用中間層組件,從而省掉建立ASP頁面的那一步。要調用Web Service,可以直接使用Microsoft SOAP Toolkit或.net這樣的SOAP客戶端,也可以使用自己開發的SOAP客戶端,然后把它和應用程序連接起來。不僅縮短了開發周期,還減少了代碼復雜度,並能夠增強應用程序的可維護性。同時,應用程序也不再需要在每次調用中間層組件時,都跳轉到相應的"結果頁"。

  2、應用程序集成

  企業級的應用程序開發者都知道,企業里經常都要把用不同語言寫成的、在不同平台上運行的各種程序集成起來,而這種集成將花費很大的開發力量。應用程序經常需要從運行的一台主機上的程序中獲取數據;或者把數據發送到主機或其它平台應用程序中去。即使在同一個平台上,不同軟件廠商生產的各種軟件也常常需要集成起來。通過Web Service,應用程序可以用標准的方法把功能和數據"暴露"出來,供其它應用程序使用。

  XML Web services 提供了在松耦合環境中使用標准協議(HTTP、XML、SOAP 和 WSDL)交換消息的能力。消息可以是結構化的、帶類型的,也可以是松散定義的。

  3、B2B的集成

  B2B 指的是Business to Business,as in businesses doing business with other businesses,商家(泛指企業)對商家的電子商務,即企業與企業之間通過互聯網進行產品、服務及信息的交換。通俗的說法是指進行電子商務交易的供需雙方都是商家(或企業、公司),她們使用了Internet的技術或各種商務網絡平台,完成商務交易的過程。

  Web Service是B2B集成成功的關鍵。通過Web Service,公司可以只需把關鍵的商務應用"暴露"給指定的供應商和客戶,就可以了,Web Service運行在Internet上,在世界任何地方都可輕易實現,其運行成本就相對較低。Web Service只是B2B集成的一個關鍵部分,還需要許多其它的部分才能實現集成。 用Web Service來實現B2B集成的最大好處在於可以輕易實現互操作性。只要把商務邏輯"暴露"出來,成為Web Service,就可以讓任何指定的合作伙伴調用這些商務邏輯,而不管他們的系統在什么平台上運行,使用什么開發語言。這樣就大大減少了花在B2B集成上的時間和成本。

  4、軟件和數據重用

  Web Service在允許重用代碼的同時,可以重用代碼背后的數據。使用Web Service,再也不必像以前那樣,要先從第三方購買、安裝軟件組件,再從應用程序中調用這些組件;只需要直接調用遠端的Web Service就可以了。另一種軟件重用的情況是,把好幾個應用程序的功能集成起來,通過Web Service "暴露"出來,就可以非常容易地把所有這些功能都集成到你的門戶站點中,為用戶提供一個統一的、友好的界面。 可以在應用程序中使用第三方的Web Service 提供的功能,也可以把自己的應用程序功能通過Web Service 提供給別人。兩種情況下,都可以重用代碼和代碼背后的數據。

  從以上論述可以看出,Web Service 在通過Web進行互操作或遠程調用的時候是最有用的。不過,也有一些情況,Web Service根本不能帶來任何好處,Web Service有以下缺點

  1、 單機應用程序

  目前,企業和個人還使用着很多桌面應用程序。其中一些只需要與本機上的其它程序通信。在這種情況下,最好就不要用Web Service,只要用本地的API就可以了。COM非常適合於在這種情況下工作,因為它既小又快。運行在同一台服務器上的服務器軟件也是這樣。當然Web Service 也能用在這些場合,但那樣不僅消耗太大,而且不會帶來任何好處。

  2、 局域網的一些應用程序

  在許多應用中,所有的程序都是在Windows平台下使用COM,都運行在同一個局域網上。在這些程序里,使用DCOM會比SOAP/HTTP有效得多。與此相類似,如果一個.net程序要連接到局域網上的另一個.net程序,應該使用.net Remoting。其實在.net Remoting中,也可以指定使用SOAP/HTTP來進行Web Service 調用。不過最好還是直接通過TCP進行RPC調用,那樣會有效得多。 

小結:從體系結構上來說Web Service大概分為5個層次:

1. Http傳輸信道 
2. XML的數據格式 
3. SOAP封裝格式 
4. WSDL的描述方式 
5. UDDI 

  總體上來講,.NET 下的 Web Service結構比較簡單,也比較容易理解和應用。在.NET結構下的WebService應用都是基於.net framework以及IIS的架構之下,所以部署(Dispose)起來相對比較容易點。

  從實現的角度來講, 首先WebService必須把暴露給客戶端的方法所在的類繼承於:System.Web.Services.WebService這個基類 ,其次所暴露的方法前面必須有[WebMethod]或者[WebMethodAttribute] 。

  WebService的運行機理 
  首先客戶端從服務器的到WebService的WSDL,同時在客戶端聲稱一個代理類(Proxy Class),這個代理類負責與WebService服務器進行Request 和Response ,當一個數據(XML格式的)被封裝成SOAP格式的數據流發送到服務器端的時候,就會生成一個進程對象並且把接收到這個Request的SOAP包進行解析,然后對事物進行處理,處理結束以后再對這個計算結果進行SOAP包裝,然后把這個包作為一個Response發送給客戶端的代理類(Proxy Class),同樣地,這個代理類也對這個SOAP包進行解析處理,繼而進行后續操作。這就是WebService的一個運行過程。  

 

 3..NET Remoting與Web Service比較

1、.net remoting使用HttpChannel,可以和WebService一樣使用Http協議的各種好處,比如傳透防火牆。但WebService是一個跨平台的東東,Java和.Net可以互相提供和引用對方的WebService,.net remoting就限制於.net平台使用。

2、.net remoting是有狀態的,是緊密耦合;web service是無狀態的(因為http是無狀態的),是松散耦合;總的來說remoting適合局域網內,對性能和響應效率要求較高的場合;而web service適合跨網絡,跨系統,對移植性和通用性要求較高的場合;remoting和web service嚴格的說都不是和J2EE的EJB對應的技術,如果一定要比較,那么部署在COM+/MTS的.net remoting組件可以和EJB對應。

3、.net remoting在局域網上的表現絕對是大大強於web services,使用tcp管道不失真的傳輸數據,從而減輕了序列化和反序列化的工作,當然使用WEB服務的時候,一台計算機存儲32位整數的方式與另一台計算機的存儲方式是不同的,因此需要像XML這樣易於理解的格式。web services 是IIS執行的,而.NET Remoting的擴展性強,使用HTTP信道和XML可以達到web services的技術的一部分,個人覺得可以把web service看成是.NET Remoting的一個特例。

 

結束語

無論是Web Service還是Microsoft.Net Remoting都可以說是博大精深。整個Web Service和Remoting的內容不是我這一篇小文所能盡述的,正如問題所示“淺談”,歡迎批評指正!

 

【請點擊下面的“綠色通道”---“關注DebugLZQ”,共同交流進步~】


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM