In the previous article, a simple WCF application was created, which is too simple to be explained. In this article, we took off all of his outerwear and checked how the lite version "helloworld" runs.
We know that WCF provides services by exposing endpoints. Therefore, the endpoint is especially important. First, analyze the endpoint.
An endpoint consists of address, binding, and contract. Address indicates the service location, contract exposes the methods provided by the Service, and binding is responsible for the communication details. This section does not discuss address and contract. Let's take a look at how to communicate directly through binding. Similarly, we create a new solution. There is no complicated first solution. This solution is more simple and only composed of two console programs, but this solution reveals the essence of communication. It laid the foundation for further discussion of the communication process. Let's talk a little bit about it. Let's take a look at this solutin.
The client is the client, and the server is the server. The code is first pasted out and explained later.
First, let's look at the server implementation:
Using system;
Using system. Collections. Generic;
Using system. LINQ;
Using system. text;
Using system. servicemodel;
Using system. servicemodel. channels;
Using system. xml;
Namespace Server
{
Class Program
{
Static void main (string [] ARGs)
{
Uri uri = new uri ("http: // localhost: 6789/helloworld ");
Basichttpbinding serverbinding = new basichttpbinding ();
Ichannellistener <ireplychannel> listener = serverbinding. buildchannellistener <ireplychannel> (URI );
Listener. open ();
Ireplychannel channel = listener. acceptchannel ();
Channel. open ();
Requestcontext context = channel. receiverequest ();
Message message = context. requestmessage;
Xmldictionaryreader reader = message. getreaderatbodycontents ();
Console. writeline ("clientmessage is:" + reader. readelementcontentasstring ());
Message replymessage = message. createmessage (messageversion. soap11, "test", "this is replymessage ");
Context. Reply (replymessage );
Channel. Close ();
Listener. Close ();
Console. Read ();
}
}
}
Explain the above Code in one sentence:
Step 1: Define a binding. Here we use basichttpbinding.
Step 2: ichannellistener <ireplychannel> listener = serverbinding. buildchannellistener <ireplychannel> (URI );
Create a channel listener channellistener. What is a channel listener? It is used to listen to client requests on the server end. If socket programming is used, it should be well understood that it will block the thread during the listener process, until the client request arrives.
Step 3: listener. open (); open the channel listener
Step 4: ireplychannel channel = listener. acceptchannel ();
Use the acceptchannel () method of listener to obtain the channel. Here I want to talk about channel sharp again, because I use the Request \ reply mode, so it is the replychannel on the server. It doesn't matter if you don't understand it here, which will be discussed later.
Step 5: Open the channel. Channel. open ();
Step 6: requestcontext context = channel. receiverequest ();
Use the receiverequest () of ireplychannel to block the thread until a service request arrives and obtain requestcontext. resquestcontext contains the client request message --- context. requestmessage.
Step 7: print the message from the client. We only print the body part.
Step 8: generate a message returned to the client. And return it to the client using the reply method of requestcontext.
Step 9: Close listener and channel.
Let's take a look at the client code:
Using system;
Using system. Collections. Generic;
Using system. LINQ;
Using system. text;
Using system. servicemodel;
Using system. servicemodel. channels;
Using system. IO;
Using system. xml;
Namespace Client
{
Class Program
{
Static void main (string [] ARGs)
{
Endpointaddress myendpoint = new endpointaddress ("http: // localhost: 6789/helloworld ");
Basichttpbinding clientbinding = new basichttpbinding ();
Ichannelfactory <irequestchannel> factory = clientbinding. buildchannelfactory <irequestchannel> ();
Factory. open ();
Irequestchannel clientchannel = factory. createchannel (myendpoint );
Clientchannel. open ();
Message message = message. createmessage (messageversion. soap11, "test", "helloworld ");
Message replymessage = clientchannel. Request (Message );
Xmldictionaryreader reader = replymessage. getreaderatbodycontents ();
Console. writeline ("server replymessage is" + reader. readelementcontentasstring ());
Clientchannel. Close ();
Factory. Close ();
Console. Read ();
}
}
}
Many client codes are the same as those on the server. I will talk about the differences with the server.
First, in the Request \ reply mode client, channel Sharp is irequestchannel. The server is ireplychannel.
Second, the client does not need to listen, so the client is a channelfactory, and the other is similar to the server.
Let's take a look at the results:
The above is the running interface of the server, and the following is the running interface of the client.
There are many new words in this article, such as channellistener, channelfactory, and channel sharp. Now we only need to have these concepts. Each word is explained separately later.
The source code can be downloaded here:/files/tylerlan/basiccommunication.rar