- WCF技術剖析(卷1)
- 蔣金楠
- 1273字
- 2018-12-27 11:32:49
3.1.3 案例演示:如何直接通過綁定進行消息通信
現在通過一個簡單的例子,演示如何直接通過綁定(在這里使用最簡單的BasicHttpBinding)進行消息通信。整個解決方案由兩個Console應用組成,它們分別模擬消息的監聽方與發送方,案例應用的結構如圖3-3所示。

圖3-3 基于綁定通信案例的應用結構
步驟一 創建請求監聽端應用程序
namespace Artech.MessagingViaBinding.Listener { class Program { static void Main(string[] args) { Uri listenUri = new Uri("http://127.0.0.1:9999/listener"); Binding binding = new BasicHttpBinding(); IChannelListener<IReplyChannel> channelListener = binding. BuildChannelListener<IReplyChannel>(listenUri); channelListener.Open();
IReplyChannel channel = channelListener.AcceptChannel (TimeSpan.MaxValue); channel.Open(); Console.WriteLine("開始監聽..."); while (true) { (TimeSpan.MaxValue); requestContext.RequestMessage); requestContext.Reply(CreateReplyMessage(binding)); } } static Message CreateReplyMessage(Binding binding) { string action = "urn:artech.com/reply"; string body = "這是一個簡單的回復消息!"; return Message.CreateMessage(binding.MessageVersion,action,body); } } }
我們通過代碼分解,對代碼執行的流程進行簡單的介紹:首先,BasicHttpBinding對象被創建出來,調用綁定對象的BuildChannelListener<IReplyChannel>方法,創建IChannelListener<IReplyChannel>對象。該方法接收一個URI類型的參數,表示監聽地址。調用Open方法開啟創建出來的信道監聽器(IChannelListener<IReplyChannel>)對象。
Uri listenUri = new Uri("http://127.0.0.1:9999/listener"); Binding binding = new BasicHttpBinding(); IChannelListener<IReplyChannel> channelListener = binding.BuildChannelListener<IReplyChannel>(listenUri); channelListener.Open();
在信道監聽器通過綁定對象被成功創建并開啟后,通過調用AcceptChannel方法創建信道棧進行請求的監聽,信道棧通過若干信道有序連接而成,方法最終返回的是位于棧頂的信道對象。
IReplyChannel channel = channelListener.AcceptChannel(TimeSpan.MaxValue); channel.Open();
一旦信道棧被成功創建,那么就可以利用它對請求消息進行接收、處理了。在本例中,通過一個無限循環來處理來自不同客戶端的消息請求。請求的接收通過IReplyChannel的ReceiveRequest方法實現。該方法接受一個TimeSpan類型參數,代表該方法從執行開始成功接受請求的時間,由于客戶端請求的頻率不確定,在這里給它指定了一個最大值。ReceiveRequest并不像我們想象的一樣返回一個代表請求消息的Message對象,而是返回一個RequestContext對象,并通過該對象將創建的回復消息回復給請求方。
注: 在請求/回復消息交換模式中,RequestContext是連接請求和回復的紐帶。RequestContext不僅僅是對請求消息的封裝,還可以用于回復消息的發送。在本例中,我們通過它的RequestMessage屬性得到請求消息,然后通過CreateReplyMessage方法創建一個回復消息,通過Reply方法回復給發送方。
RequestContext requestContext = channel.ReceiveRequest(TimeSpan.MaxValue); Console.WriteLine("接收到請求消息:\n{0}", requestContext.RequestMessage); requestContext.Reply(CreateReplyMessage(binding));
在創建回復消息的時候,須要考慮消息的版本問題。在WCF中,消息版本通過System.ServiceModel.Channels.MessageVersion類表示,一般消息的版本包含兩個部分的內容:SOAP的版本和WS-Addressing的版本,它們分別通過System.ServiceModel.Channels. AddressingVersion和System.ServiceModel.Channels.AddressingVersion表示。對一個綁定對象來說,并不是所有的MessageVersion都支持,為此,在創建回復消息的時候,通過具體的綁定對象確定回復消息的MessageVersion。
static Message CreateReplyMessage(Binding binding) { string action = "urn:artech.com/reply"; string body = "這是一個簡單的回復消息!"; return Message.CreateMessage(binding.MessageVersion, action, body); }
步驟二 創建消息發送端應用程序
namespace Artech.MessagingViaBinding.Sender { class Program { static void Main(string[] args) { Uri listenUri = new Uri("http://127.0.0.1:9999/listener"); Binding binding = new BasicHttpBinding(); IChannelFactory<IRequestChannel> channelFactory = binding.BuildChannelFactory<IRequestChannel>(); channelFactory.Open(); IRequestChannel channel = channelFactory.CreateChannel(new EndpointAddress(listenUri)); channel.Open(); Message replyMessage = channel.Request(CreateRequestMessage (binding)); Console.WriteLine("接收到回復消息\n{0}", replyMessage); Console.Read(); } static Message CreateRequestMessage(Binding binding) { string action = "urn:artech.com/request"; string body = "這是一個簡單的請求消息!"; return Message.CreateMessage(binding.MessageVersion,action,body); } } }
發送端的程序和監聽端類似,在監聽程序中,通過綁定創建了IChannelListener<IReplyChannel>對象,并調用AcceptChannel方法創建監聽信道棧并進行消息的接收與處理。與之相對,在客戶端我們通過綁定創建IChannelFactory<IRequestChannel>對象,并通過該對象創建信道棧進行請求消息的發送。
Binding binding = new BasicHttpBinding(); IChannelFactory<IRequestChannel> channelFactory = binding.BuildChannelFactory<IRequestChannel>(); channelFactory.Open();
輸出結果
成功創建了請求監聽端和消息發送端的應用程序之后,先后運行這兩個控制臺的應用程序,對于監聽端,將會出現如圖3-4的輸出結果。<s:Envelope>包含的內容正是在消息發送端生成并發送的SOAP消息的內容。

圖3-4 基于綁定通信案例監聽端運行結果
由于監聽端在接收到請求消息后,向請求端返回了一個回復消息,這個回復消息將會成功輸出到消息請求端。圖3-5是消息發送端運行時的真實輸出結果。

圖3-5 基于綁定通信案例請求端運行結果
- 大學計算機基礎(第三版)
- Mastering Objectoriented Python
- Python從菜鳥到高手(第2版)
- 實用防銹油配方與制備200例
- Yocto for Raspberry Pi
- 微信小程序項目開發實戰
- Mastering Business Intelligence with MicroStrategy
- Python深度學習原理、算法與案例
- Practical Game Design with Unity and Playmaker
- Programming Microsoft Dynamics? NAV 2015
- Photoshop CC移動UI設計案例教程(全彩慕課版·第2版)
- PHP 8從入門到精通(視頻教學版)
- 大數據時代的企業升級之道(全3冊)
- Learning Alfresco Web Scripts
- MySQL從入門到精通