WCF post-transfer series (9): Deep-channel Programming Model Part 2-instance

Source: Internet
Author: User
Introduction

Essentially, WCF is a communication service framework that allows us to use different transmission protocols and different message encoding formats to interact with different WS-* series standards, all these details are handled by the channel stack. In the WCF topic series (8): Deep Channel Programming Model Part 1-design, I have a deep understanding of the channel model in WCF. In this article, I will explain through examples how the server receives messages and how the client sends messages in the channel model.

Server Channel

This article will not use the WCF programming model, but directly use the channel model for communication, which will help us further deepen our understanding of the server's message processing, in the first step of listening to and receiving messages on the server, you need to create a binding. You can either use the built-in binding in WCF or use custom binding. The following Code creates a CustomBinding:

// Create custom BindingElement [] bindingElements = new BindingElement [2]; bindingElements [0] = new TextMessageEncodingBindingElement (); bindingElements [1] = new HttpTransportBindingElement (); customBinding binding = new CustomBinding (bindingElements );

HttpTransportBindingElement is added here, so the generated channel Stack has an HTTP transmission channel and a text message encoder is used. Next, call the BuildChannelListener method of mbinding just created to construct the channel listener. You need to specify the listening base address and binding parameters, and call the Open () method to Open the channel listener, I believe you will remember that the Open () method is defined in the ICommunicationObject interface, as shown in the following code:

// Use custom binding to create the channel listener IChannelListener <IReplyChannel> listener = binding. buildChannelListener <IReplyChannel> (new Uri ("http: // localhost: 8887/StringService"), new BindingParameterCollection (); // listen to the listener message. open (); Console. writeLine ("Listening for incoming channel connections ");

Now we are listening for incoming messages. Because we have used the request response message exchange mode, the listener returns a channel that implements the IReplyChannel. To receive messages through this channel, we first call the Open () method (this method is still defined in ICommunicationObject) to put it in a ready state for communication. Then, we call the ReceiveRequest () method, which will be blocked until the message reaches, as shown in the following code:

// Create the Reply channel IReplyChannel = listener. acceptChannel (); Console. writeLine ("Channel accepted. listening for messages "); channel. open (); RequestContext request = channel. receiveRequest ();

When the ReceiveRequest () method returns a RequestContext, use its RequestMessage attribute to obtain the received message. The Action and content of the Output Message. To send a reply, create a new reply message in this example. It will add the string data we received in the request, and then pass it back. Then, call the Reply () method to send a Reply message, as shown in the following code:

// Read the request Message message = request. requestMessage; Console. writeLine ("Message Received"); Console. writeLine ("Message Action: {0}", message. headers. action); string body = message. getBody <string> (); Console. writeLine ("Message Content: {0}", body); // Send Response Message replymessage = Message. createMessage (binding. messageVersion, "http://www.cnblogs.com/TerryLee/Encode", "Hello:" + body); request. reply (replymessage );

Finally, do not forget to release the resource and disable the channel listener, channel, request message, request context, and so on. The code below is as follows:

// Release object message. Close (); request. Close (); channel. Close (); listener. Close ();

The complete code is as follows:

/// <Summary> /// Author: TerryLee // Url: http://www.cnblogs.com/terrylee/// </summary> static void Main () {// create custom BindingElement [] bindingElements = new BindingElement [2]; bindingElements [0] = new TextMessageEncodingBindingElement (); bindingElements [1] = new HttpTransportBindingElement (); customBinding binding = new CustomBinding (bindingElements); // use custom binding to create a channel listener IChannelListener <IReplyChannel> listener = binding. buildChannelListener <IReplyChannel> (new Uri ("http: // localhost: 8887/StringService"), new BindingParameterCollection (); // listen to the listener message. open (); Console. writeLine ("Listening for incoming channel connections"); // create the Reply channel IReplyChannel channel = listener. acceptChannel (); Console. writeLine ("Channel accepted. listening for messages "); channel. open (); RequestContext request = channel. receiveRequest (); // read the request Message message = request. requestMessage; Console. writeLine ("Message Received"); Console. writeLine ("Message Action: {0}", message. headers. action); string body = message. getBody <string> (); Console. writeLine ("Message Content: {0}", body); // Send Response Message replymessage = Message. createMessage (binding. messageVersion, "http://www.cnblogs.com/TerryLee/Encode", "Hello:" + body); request. reply (replymessage); // release the object message. close (); request. close (); channel. close (); listener. close (); Console. writeLine ("Press Enter to exit"); Console. readLine ();}

As shown in Running Server 1, The ReceiveRequest () method is blocked because no message arrives:

Figure 1

Client Channel

After completing the work on the server side, let's take a look at how to use the channel model to communicate directly on the client side. Consistent with the server, the first step of the request message is to create a binding because both parties need to reach an agreement on the communication details through binding. The custom binding is the same as that on the server, as shown in the following code:

// Create BindingElement [] bindingElements = new BindingElement [2]; bindingElements [0] = new TextMessageEncodingBindingElement (); bindingElements [1] = new HttpTransportBindingElement (); customBinding binding = new CustomBinding (bindingElements );

Next, we need to construct the channel factory using the binding we just created. As mentioned in the previous article, the receiver of the message uses the channel listener, while the requester of the message uses the channel factory. This time, BuildChannelFactory () is used () method to Construct and open the channel factory, as shown in the following code:

// Use bind to create the channel factory IChannelFactory <IRequestChannel> factory = binding. buildChannelFactory <IRequestChannel> (new BindingParameterCollection (); // open the channel factory. open (); Console. writeLine ("Channel factory opened ");

Now, use the CreateChannel () method of the channel factory to create the IRequestChannel. After obtaining the channel, call its Open () method to make it ready for communication, as shown in the following code:

// CREATE Request channel IRequestChannel channel = factory. createChannel (new EndpointAddress ("http: // localhost: 8887/StringService"); channel. open (); Console. writeLine ("Request channel opened ");

After opening the channel, you can create a message and use the channel's Request () method to send the Request and wait for the response. Here, the message content we send is "TerryLee". When this method returns, we will be able to get a reply message and read the message to find the reply content at the endpoint, as shown in the following code:

// Create the request Message requestmessage = Message. createMessage (binding. messageVersion, "http://www.cnblogs.com/TerryLee/Encode", "TerryLee"); // send the request Message and receive the Response Message replymessage = channel. request (requestmessage); Console. writeLine ("Reply message received"); Console. writeLine ("Reply action: {0}", replymessage. headers. action); string data = replymessage. getBody <string> (); Console. writeLine ("Reply content: {0}", data );

Finally, the resource is released, and the channel factory, channel, and request message are closed, as shown in the following code:

replymessage.Close();channel.Close();factory.Close();

The complete client code is:

/// <Summary> /// Author: TerryLee // Url: http://www.cnblogs.com/terrylee/// </summary> public static void Main () {// create BindingElement [] bindingElements = new BindingElement [2]; bindingElements [0] = new TextMessageEncodingBindingElement (); bindingElements [1] = new HttpTransportBindingElement (); customBinding binding = new CustomBinding (bindingElements); // use bind to create a channel factory IChannelFactory <IRequestChannel> factory = binding. buildChannelFactory <IRequestChannel> (new BindingParameterCollection (); // open the channel factory. open (); Console. writeLine ("Channel factory opened"); // CREATE Request channel IRequestChannel Channel = factory. createChannel (new EndpointAddress ("http: // localhost: 8887/StringService"); channel. open (); Console. writeLine ("Request channel opened"); // creates the Request Message requestmessage = Message. createMessage (binding. messageVersion, "http://www.cnblogs.com/TerryLee/Encode", "TerryLee"); // send the request Message and receive the Response Message replymessage = channel. request (requestmessage); Console. writeLine ("Reply message received"); Console. writeLine ("Reply action: {0}", replymessage. headers. action); string data = replymessage. getBody <string> (); Console. writeLine ("Reply content: {0}", data); replymessage. close (); channel. close (); factory. close (); Console. writeLine ("Press Enter to exit"); Console. readLine ();}

Server 2 is shown in the final run time:

Figure 2

Client 3:

Figure 3

Learn more

Now let's review the Knowledge mentioned in the previous article. The channel object model is a set of core interfaces necessary to implement channels, channel listeners, and channel factories. Some base classes are also provided to help with custom implementation. We can see that the channel model has three most important interfaces: Channel, channel listener, and channel factory. Each channel implements one or more interfaces, called channel shape interfaces or channel shapes. The channel listener is responsible for listening for incoming messages, that is, at the message receiving end, then, these messages are sent to the above layer through the channel created by the channel listener. The channel factory is responsible for creating a channel for sending messages, that is, when the message sender is disabled at the Channel factory, close all channels created by the channel factory. 4:

Figure 4

Based on the sample code in this article, I believe you can have a deeper understanding of Figure 4.

Summary

This article uses a simple example to show how the server receives messages and how the client sends messages in the channel model.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.