官术网_书友最值得收藏!

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 基于綁定通信案例請求端運行結果

主站蜘蛛池模板: 龙海市| 乐安县| 报价| 上思县| 葵青区| 高密市| 布尔津县| 海丰县| 朝阳区| 河津市| 农安县| 安康市| 庄河市| 大安市| 义马市| 泰顺县| 永城市| 宁海县| 饶阳县| 安龙县| 龙口市| 巴彦淖尔市| 崇明县| 奉化市| 台北县| 临沭县| 邢台市| 庆城县| 宁明县| 舞阳县| 留坝县| 龙海市| 华坪县| 竹溪县| 大石桥市| 岫岩| 翁源县| 五家渠市| 临湘市| 望都县| 东明县|