日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

WCF中的管道——管道类型

發布時間:2024/7/19 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 WCF中的管道——管道类型 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

管道是所有消息進出WCF應用程序的渠道。它的職責是以統一的方式編制和提供消息。管道中定義了傳輸、協議和消息攔截。管道以層級結構的形式匯總,就創建了一個管道棧。管道棧以分層的方式進行通信并處理消息。例如,一個管道棧可以使用一個TCP協議管道和一個交互協議管道共同組建。這樣的一個管道棧就可以允許從客戶端島服務器端,通過網絡發送和接收使用TCP協議和交互式協議的消息。

管道棧的目的是將一個消息轉化為發送者和接收者之間都兼容的格式來傳遞消息。有兩種類型的管道可以使用:傳輸管道和協議管道。傳輸管道始終防止在管道棧的底部,它的責任是使用一個傳輸協議傳遞消息。WCF提供了許多傳輸協議,包括HTTP、TCP、MSMQ、Peer-to-peer以及命名管道。協議管道駐留在傳輸管道或其他協議管道的頂端。由于協議管道駐留在其他管道的頂端,他們通常稱為分層管道。協議管道的職能是通過翻譯和修改消息來實現線路級別上的協議。WCF提供許多類型的協議管道。例如包括實現安全支持的、傳輸支持的以及可靠性支持的協議管道。

提示:傳輸協議

WCF提供多個傳輸管道,包括HTTP、TCP、MSMQ、PtoP以及命名管道。其他的傳輸方式在示例代碼中或通過第三方插件也可以使用,這樣就實現更廣泛的傳輸,包括SMTP、FTP、UDP、WebSphere MQ,以及SQL Server 代理。這些傳輸管道大多可以在http://wcf.netfx3.com的網站上找到。UDP傳輸管道可以在Windows SDK中找到。針對WebSphere MQ可以在IBM的alphaWorks網站上找到。

通信發生時,客戶端和服務端需要實例化一個互相匹配的管道棧。在.NET應用程序之間,在客戶端和服務端使用同一管道棧是典型的做法。一般來說,他們的功能必須匹配。我們使用綁定來簡化管道棧的創建。一個綁定捕獲管道棧的配置,并知道如何在運行時創建一個管道棧。綁定構建了一個綁定元素的集合,他們通常代表管道棧中的管道。綁定和綁定元素將會在后面進行討論。

WCF管道架構允許通過應用程序抽象的溝通,從而提供了極大的靈活性。這就使開發者構建可以暴露給多個通信機制的服務,這就使應用程序服務可以根據需求變化的時間來改變服務。例如,一個WCF服務暴露在兩個.NET應用程序之間,而這個服務可以輕易的暴露給Java應用程序而不需要更改應用程序本身。同時它還支持如互操作性、持久化消息,而且傳輸可以根據需求的變化輕松的附加到WCF服務上。之前的微軟的技術(如ASP.NET Web服務、.NET Remoting、企業服務或MSMQ)要求你為每個新的通信形式重寫應用程序的操作。而使用WCF,你現在可以選擇你想要的通信技術,而不需要大量的重寫應用程序。

WCF的功能還針對如何使用層級結構組建一個管道棧而提供非常大的靈活性。如下圖所示,一個消息如何從一個WCF客戶端應用程序管道棧傳遞到一個給定的服務端。該服務的管道棧監聽消息,然后將這些消息指派到服務端應用。

一個管道棧是一系列使用綁定元素已配置好的管道。一個預定義的管道棧也叫做一個綁定。一個綁定由一系列的綁定元素構成,就像一個管道棧由一系列的管道組成一樣。在這個棧的頂端是一個協議管道。協議管道與一個消息相互作用,而且更有利于安全、可靠的消息、傳輸和日志等功能。一個管道棧中可能有多個協議管道,他們依賴于不同的功能需求。

傳輸管道負責通過一個轉換協議,如TCP或HTTP,發送字節信息。他們也負責使用一個編碼形式來將一個消息轉化為字節數組以便于傳輸。這種編碼形式的職能是把消息從它本身的XML表現形式轉化為字節數組的形式。編碼器使用綁定元素暴露給傳輸管道。傳輸通道通過MessageEncoder類查看綁定內容。如果沒有匹配項,傳輸管到會定義一個默認的消息編碼器。

提示:管道棧有一個傳輸器和一個編碼器

管道棧有至少一個傳輸器和一個編碼器。通常傳輸器將定義一個默認的編碼器來使用。例如tcpTransport傳輸管道指定使用binaryMessageEncoding。這些都是WCF中實現一個管道棧所必須的。協議管道在編輯管道棧時是可選的。

管道類型

WCF支持三種不同的消息交換模式:單項、全雙工和請求。為了方便每種模式,WCF提供了10種不同的接口,叫做管到類型。其中的5個是IOutputChannel、IInputChannel、IDuplexChannel、IRequestChannel以及IReplyChannel。這些類型對于支持會話狀態來說都是對等的。他們包括IOutputSessionChannel、IInputSessionChannel、IDuplexSessionChannel、IRequestSessionChannel以及IReplySessionChannel。這些接口在管道棧中實現不同的消息交換模式。在這里我們會看到每種通信模式和各種接口的關系。

單向通信模式

單向通信模式中,消息只在一個方向上發送,就是從客戶端到服務端。當發送者并不需要一個信息馬上回應時,通常應用單向通信;此時發送者只需要一個消息已被發送的確認。消息發送后,通信就結束。用于實現單向通信的兩個接口是IOutputChannel以及IInputChannel接口。下圖顯示了,單向通信中,消息是如何在客戶端和服務端流動的。在這個模式中,IOutputChannel接口負責發送消息,而IInputChannel負責接收消息。下面代碼顯示了一個客戶端程序使用IOutputChannel管道來發送消息。

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.ServiceModel; using System.ServiceModel.Channels;namespace WCFOneWayChannelClient {class Program{static void Main(string[] args){BasicHttpBinding binding = new BasicHttpBinding();BindingParameterCollection parameters = new BindingParameterCollection();Message m = Message.CreateMessage(MessageVersion.Soap11,"urn:sendmessage");IChannelFactory<IOutputChannel> factory = binding.BuildChannelFactory<IOutputChannel>(parameters);IOutputChannel channel = factory.CreateChannel(new EndpointAddress("http://localhost/sendmessage"));channel.Send(m);channel.Close();factory.Close();}} }

全雙工通信

雙工通信使用兩個單向管道,組合成第三個接口叫做IDuplexChannel,如下圖所示。雙工通信與單向或請求響應模式相比,優點在于消息可以在客戶端和服務端之間互相發送。

全雙工通信的一個例子是一個事件通知系統。一個服務端將會發送事件到客戶端,客戶端接收事件。客戶端提供一個端點,以便服務端可以通過這個端點將消息發送到客戶端。然后服務端使用端點來發送消息到客戶端。下面代碼顯示了一個例子,一個客戶端使用IDuplexChannel管道類型。

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.ServiceModel; using System.ServiceModel.Channels;namespace WCFDuplexChannelClient {class Program{static void Main(string[] args){NetTcpBinding binding = new NetTcpBinding();BindingParameterCollection parameters = new BindingParameterCollection();Message m = Message.CreateMessage(MessageVersion.Soap12WSAddressing10,"uru:sendmessage");IChannelFactory<IDuplexChannel> factory = binding.BuildChannelFactory<IDuplexChannel>(parameters);IDuplexChannel channel = factory.CreateChannel(new EndpointAddress("net.tcp://localhost/sendmessage/"));channel.Send(m);channel.Close();factory.Close();}} }

請求響應通信

請求響應通信是一種特殊的雙向通信,其中每個請求都有明確的響應,而且它總是由客戶端發起。客戶端發送了請求后,它就必須等待響應,然后才可以發送另一個請求。請求響應通信的通常用法是,從一個瀏覽器發送的一個HTTP請求。瀏覽器生成一個HTTP請求到服務端,如GET或POST,服務端處理請求,然后一個響應被回發。WCF使用IRequestChannel和IReplyChannel接口處理請求響應通行。如下圖所示:

下面代碼顯示了一個客戶端應用程序使用IRequestChannel來發送一個消息。注意,Request方法以返回值參數來返回響應消息。

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.ServiceModel; using System.ServiceModel.Channels;namespace WCFRequestReplyChannelClient {class Program{static void Main(string[] args){BasicHttpBinding binding = new BasicHttpBinding();BindingParameterCollection parameters = new BindingParameterCollection();Message request = Message.CreateMessage(MessageVersion.Soap11,"urn:sendmessage");IChannelFactory<IRequestChannel> factory = binding.BuildChannelFactory<IRequestChannel>(parameters);IRequestChannel channel = factory.CreateChannel(new EndpointAddress("http://localhost/sendmessage/"));Message response = channel.Request(request);channel.Close();factory.Close();}} }

類型變更

內置的HTTP協議內在具有請求響應的性質,因此HTTP傳輸管道使用請求響應管道類型。其它的通信模式,如單向和雙工,通過HTTP完成類型變更。通過分層協議管道頂端的傳輸管道,以支持單向或雙工通信。下面的代碼顯示一個自定義的綁定,來分層一個單項類型管道綁定元素,OneWayBindingElement,在HTTP傳輸的頂端。后面的部分中,我們會看到使用CompositeDuplexBindingElement綁定元素實現類型變更的更優化的案例。

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.ServiceModel; using System.ServiceModel.Channels;namespace WCFShapeChangingClient {class Program{static void Main(string[] args){CustomBinding binding = new CustomBinding(new OneWayBindingElement(),new TextMessageEncodingBindingElement(),new HttpTransportBindingElement());}} }

操作契約和管道類型

管道使用管道類型來實現對多種消息交換模式的支持。例如,一個基于TCP的傳輸管道將實現IInputChannel和IOutputChannel,因為這些傳輸本質上是單向模式。基于其它傳輸的其它協議,如TCP,可以實現多個管道類型。開發人員并不直接操作管道的類型。相反,WCF會基于一個服務的操作契約選擇管道的類型。下面表格列出了你可以在操作契約中設置的各種屬性以及結果管道類型。注意,大多數管道類型具有無會話狀態和會話狀態感知兩種變化。會話感知管道從客戶端向服務端傳遞一個標識符。這就可以在服務端和客戶端之間維護會話狀態。這類似于ASP.NET中的狀態管理。WCF中沒有狀態管理功能,但是你可以使用會話狀態與實例來管理狀態。實例管理會在后面介紹。

不是所有的管道都實現了每個接口。如果基礎管道不支持某個特定的管道類型,WCF將嘗試適配一個存在的管道類型以滿足需要。例如,如果一個單向管道沒有實現IInputChannel和IOutputChannel接口,,WCF將會嘗試使用IDuplexChannel或IRequestChannel/IReplyChannel實例。

管道監聽

管道監聽器構成了WCF中基本的服務端通信。他們負責監聽進入的消息,創建管道棧以及提供指向應用程序棧頂的引用。他們從傳輸管道或從管道棧中的管道中接收消息。大多數開發人員不會直接操作監聽器。他們使用ServiceHost類來宿主那些使用管道監聽器監聽消息的服務。我們會在介紹宿主時詳細介紹ServiceHost類。下面代碼顯示了一個管道監聽器被創建用來接收消息。綁定的BuildChannelListener方法基于特定類型的管道構建一個管道監聽器。這個例子中,我們使用BasicHttpBinding和IReplyChannel類型。

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.ServiceModel; using System.ServiceModel.Channels; using System.Runtime.Serialization;namespace WCFChannelListenersServer {class Program{static void Main(string[] args){BasicHttpBinding binding = new BasicHttpBinding(BasicHttpSecurityMode.None);Uri address = new Uri("http://localhost/request");BindingParameterCollection bpc = new BindingParameterCollection();Console.WriteLine("Starting service...");IChannelListener<IReplyChannel> listener = binding.BuildChannelListener<IReplyChannel>(address, bpc);listener.Open();IReplyChannel channel = listener.AcceptChannel();channel.Open();Console.WriteLine("Service started!");Console.WriteLine("Waiting for request...");RequestContext request = channel.ReceiveRequest();Message message = request.RequestMessage;string data = message.GetBody<string>();Message replymessage = Message.CreateMessage(message.Version,"http://localhost/reply",data);request.Reply(replymessage);Console.WriteLine("Service stopped!");message.Close();request.Close();channel.Close();listener.Close();Console.ReadLine();}} }

管道工廠

管道工廠創建一個管道來發送消息并維護它創建的管道所有權。大多數開發者從不會直接使用管道工廠。相反,他們會使用一個類,繼承自ClientBase<>,這個類通常由svcutil.exe或添加服務引用操作生成。然而,重要的是要了解管道工廠,因為他們構成WCF客戶端通信的基礎。

提示,管道工廠擁有它們的管道。管道監聽器和工廠之間最重要的區別是管道工廠負責關閉所有相關聯的管道;管道監聽器不是。這種區別使管道監聽器可以獨立的關閉他們依賴的管道。

下面代碼顯示了使用一個管道工廠來調用服務。這是在上面例子中服務的客戶端。這段代碼使用綁定的CreateChannel方法來創建一個新的管道。

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.ServiceModel; using System.ServiceModel.Channels; using System.Runtime.Serialization;namespace WCFChannelFactoryClient {class Program{static void Main(string[] args){BasicHttpBinding binding = new BasicHttpBinding(BasicHttpSecurityMode.None);IChannelFactory<IRequestChannel> factory = binding.BuildChannelFactory<IRequestChannel>(new BindingParameterCollection());factory.Open();IRequestChannel channel = factory.CreateChannel(new EndpointAddress("http://localhost/request"));channel.Open();Message requestMessage = Message.CreateMessage(MessageVersion.Soap11,"http://chinasofti.com/reply","This.is the body data");Console.WriteLine("Sending message...");Message replymessage = channel.Request(requestMessage);string data = replymessage.GetBody<string>();Console.WriteLine("Reply received!");requestMessage.Close();replymessage.Close();channel.Close();factory.Close();Console.ReadLine();}} }

ChannelFactory<>

WCF中的兩個類代表管道工廠:ChannelFactory和ChannelFactory<>。他們可能看起來比較相似,但是實際上他們做不同的事情。ChannelFactory<>類用在高級的情況下,如多個客戶段需要創建時。本質上它與一個給定的ChannelFactory一起工作,但是它不負責創建管道棧。ChannelFactory<>類用來使用一個特定的服務契約類型定義一個類。下面代碼顯示一個案例,其中一個使用ChannelFactory<>類調用一個實現了IStockQuoteService接口的服務端。

提示,使用狀態機制和ChannelFactory<>。使用狀態機制關閉ChannelFactory時要小心。下面代碼顯示了在服務調用代碼的外圍使用try…catch以便從服務端拋出的錯誤都能被捕獲。如果我們不使用try…catch,任何異常都有可能在使用過程中冒出來。從這點上來說,管道工廠應該在它關閉后拋出異常。這有可能使之前的錯誤從服務調用中暴露出來。我們使用兩個try…catch塊,使我們可以從服務調用中抓住任何異常。

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.ServiceModel; using System.ServiceModel.Channels;namespace WCFChannelFactoryClassClient {class Program{static void Main(string[] args){try{using (ChannelFactory<IStockQuoteService> cf = new ChannelFactory<IStockQuoteService>()){IStockQuoteService service = cf.CreateChannel();try{double value = service.GetQuotr("ChinaSofti");}catch (Exception ex){//check exception from call to GetQuoteConsole.WriteLine(ex.ToString());}}}catch (Exception ex){//check exception for creating channelConsole.WriteLine(ex.ToString());}Console.ReadLine();}} }

ICommunicationObject

WCF中,ICommunicationObject接口是所有通信對象的基礎(管道、管道工廠、管道監聽等等)。開發人員要想定義自定義管道或者直接操作管道時,就需要了解這個接口。WCF中的通信對象需要實現一個特殊的狀態機。這個狀態機表現了所有通信對象運行的狀態。這種方法類似于其它對象(如sockets).ICommunicationObject接口的目的是實現狀態機。這允許WCF對所有通信對象形同看待,并抽象他們的基本實現。

下面代碼顯示了狀態機制中提供的通信狀態枚舉。

public enum CommunicationState {Created, Opening, Opened, Closing, Closed, Faulted }

CommunicationState枚舉列出了通信對象的六個狀態。所有通信對象的初始狀態是Created。當通信對象被實例化時,這個狀態表明該通信對象進入系統。所有通信對象的最終狀態是Closed。沿著這個方式,ICommunicationObject接口上的方法被一一調用,從而將通信對象從一個狀態轉換到另一個狀態。例如,Open方法被調用,通信對象的狀態從Created狀態轉換到了Opened狀態。下圖展示了一個狀態圖以表明通信對象在狀態與狀態之間的變化。

通信對象的一個例子就是ClientBase<>類,這個類是從添加服務引用操作或svcutil.exe生成客戶端代碼時的基本實現類。

注意,不能重復使用客戶端。當一個通信對象已經從Opened狀態轉換到Closing或Faulted狀態后,就不能回滾。這就意味著,通信對象不能返回Opened狀態,除非首先重復創建這個通信對象。因此,客戶端需要在他們被關閉后,重新創建。

五個事件(Opening,Opened,Closing,Closed和Faulted)是ICommunicationObject支持的方法。這些事件用來標示代碼狀態的轉換。

提示,客戶端通知。通常情況下應用程序會維護一個客戶端代理的引用。這種情況下,使用狀態轉換事件,當客戶端代理進入Faulted狀態時用作通知(并最終轉換到Closed狀態)使客戶端和服務端之間的通信能夠維持下去。

ICommunicationObject接口通常用來將一個現有通信對向轉換為接口類型,以獲得訪問ICommunicationObject中暴露的方法和事件。然而,其它時候,你想要創建一個新的通信對象來擴展WCF的能力。在這種情況下,WCF提供一個抽象基類調用CommunicationObject,它提供了ICommunicationObject接口的實現以及狀態機制的關聯。下面代碼顯示一個由svcutil.exe生成的StockQuoteServiceClient。這個客戶端繼承自ClientBase<>類。代碼顯示這個客戶端被轉化為ICommunicationObject接口,以便我們可以訪問通信事件。

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.ServiceModel; using System.ServiceModel.Channels;namespace WCFICommunicationObjectClient {class Program{static void Main(string[] args){string symbol = "ChinaSofti";double value;StockQuoteServiceClient client = new StockQuoteServiceClient();ICommunicationObject commobj = (ICommunicationObject)client;commobj.Closed += new EventHandler(commobj_Closed);commobj.Faulted += new EventHandler(commobj_Faulted);value = client.GetQuote(symbol);Console.WriteLine("{0} @ $ {1}",symbol,value);Console.ReadLine();}static void commobj_Faulted(object sender, EventArgs e){//Handle Closed Event}static void commobj_Closed(object sender, EventArgs e){//Handle Faulted Event}} }

轉載于:https://www.cnblogs.com/zhangdong/archive/2010/01/13/1646484.html

創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎

總結

以上是生活随笔為你收集整理的WCF中的管道——管道类型的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。