Luohe first recognized WCF4 and wcf4

Source: Internet
Author: User

Luohe first recognized WCF4 and wcf4

Refer:

Http://blog.csdn.net/anlun/article/details/44860821

Article 4 Communication-ChannelFactory

 

Through the previous articles, we have briefly understood the server-client model of WCF. We can establish a simple WCF communication program and host our services in IIS. We can't help but lament the simplicity of the WCF model. communication can be established with just a few lines of code and configuration. However, there are still many questions: how does a server build services? What happens after a client calls an operation? What exactly is metadata? And so on. Our understanding of WCF is still in its infancy, and we will feel that there are many such mysteries.

 

Although we live in a beautiful application-layer space built for us by WCF, we should strive to know what it means for any technology, understanding the underlying knowledge helps us better understand upper-layer applications. Therefore, when we first started learning, it was very helpful to be slower and more refined.

 

Now we know the most basic thing. The client and server need to communicate with each other. How does this communication happen? According to our previous study, we have defined the coordination and implementation on the server, configured the public endpoint, enabled metadata exchange, and added service references on the client, then a new object named XXXClient is created. This object has all the methods in the service agreement and can be called directly. Think about it? God, how did this happen ?!

 

The server defines the protocol and implementation and exposes the endpoint. This does not seem to be a problem. Although we do not know the underlying implementation, it is always logical, but how does the client get everything done by adding a service reference? It seems that the added service reference is secretly involved.

 

Open the client we created in the second article (if you have created a client for the IIS service in the third article, you can open it as well, and I will use it) to see what is in the service reference.

1. Service reference

In the solution browser, click "show all files" at the top, and then expand the service reference.

There are so many xsd files that we may know about the framework description, What Is wsdl, and disco (disco ?) What is it.

There is a cs file, which should be clearly understood.

// -------------------------------------------------------------------------------- // <Auto-generated> // This code is generated by the tool. // Runtime version: 4.0.30319.42000 // changes to this file may lead to incorrect behavior. If // re-generates code, these changes will be lost. // </Auto-generated> // -------------------------------------------------------------------------------- namespace HelloWcfClent. myService {[System. codeDom. compiler. generatedCodeAttribute ("System. serviceModel "," 4.0.0.0 ")] [System. serviceModel. serviceContractAttribute (ConfigurationName = "MyService. IHelloWcfService ")] public interface IHelloWcfService {[System. serviceModel. operationContractAttribute (Action =" http://tempuri.org/IHelloWcfService/HelloWcf ", ReplyAction =" http://tempuri.org/IHelloWcfService/HelloWcf Response ")] string HelloWcf (); [System. ServiceModel. OperationContractAttribute (Action =" http://tempuri.org/IHelloWcfService/HelloWcf ", ReplyAction =" http://tempuri.org/IHelloWcfService/HelloWcf Response ")] System. threading. tasks. task <string> HelloWcfAsync ();} [System. codeDom. compiler. generatedCodeAttribute ("System. serviceModel "," 4.0.0.0 ")] public interface IHelloWcfServiceChannel: HelloWcfClent. myService. IHelloWcfService, System. serviceModel. IClientChannel {} [System. diagnostics. debuggerStepThroughAttribute ()] [System. codeDom. compiler. generatedCodeAttribute ("System. serviceModel "," 4.0.0.0 ")] public partial class HelloWcfServiceClient: System. serviceModel. clientBase <HelloWcfClent. myService. IHelloWcfService>, HelloWcfClent. myService. IHelloWcfService {public HelloWcfServiceClient () {} public partition (string endpointConfigurationName): base (endpointConfigurationName) {} public partition (string endpointConfigurationName, string remoteAddress): base (endpointConfigurationName, remoteAddress) {} public HelloWcfServiceClient (string endpointConfigurationName, System. serviceModel. endpointAddress remoteAddress): base (endpointConfigurationName, remoteAddress) {} public HelloWcfServiceClient (System. serviceModel. channels. binding binding, System. serviceModel. endpointAddress remoteAddress): base (binding, remoteAddress) {} public string HelloWcf () {return base. channel. helloWcf ();} public System. threading. tasks. task <string> HelloWcfAsync () {return base. channel. helloWcfAsync ();}}}

We didn't write such a pile of code. Initially, it seems that there are several classes/interfaces, IHelloWCF. This should be a service agreement, probably downloaded from the server, HelloWCFClient, this is our client proxy. We used it before. It was defined here, but what is the ClientBase inherited later, so many constructors are also overloaded. There is also an IHelloWCFChannel interface. We cannot find any solution to use it. Why is it defined here?

Let's not go over the specific meanings of these codes. We can't help but feel a little worried about VS2010. If VS2010 and IDE are absent, what should we do if "add service reference" is absent?

Although we expect that VS2010 will not disappear, we can always enjoy the convenience it provides to us. But we are studying it here today. We may look at the control level to a lower level. Let's take a look at the following.

2. We write communication by ourselves.

How exactly does communication happen? In short, there is a channel between two endpoints. In fact, the client also has an endpoint. The client will establish a channel between the two endpoints, then, encapsulate the call to the server service as a message sent along the channel. After the server obtains the message, it establishes a service object on the server and then executes the operation to encapsulate the return value into a message and send it to the client.

The process is probably like this. In some cases, it may be less rigorous, but we can understand this logic. In this case, the main part of the communication work is on the client side. He wants to establish a channel and send messages, and the server is basically waiting for the request.

What does the client need to complete this series of operations? Metadata and some service classes. The service class is provided by the System. ServiceModel class library, with only metadata difference. When it comes to metadata, we can't help but take a breath. Is that a bunch of xsd ooxx stuff? I don't think so. In this example, metadata includes service agreement, server endpoint address, and binding. Yes, that's all. Do we have to get the metadata from the server through metadata exchange and download? Of course not. In this example, the server is designed. We certainly understand the metadata in these three aspects.

 

So let's get to hell with the service reference. Let's do it ourselves.

(1) create a client.

We are very familiar with this process. We have established a console application without doing anything else. Only the refreshing program. cs

 

(2) Add necessary references

As mentioned above, the initiation of client communication requires the support of some service classes which are defined in System. ServiceModel. Therefore, we need to add reference to this Assembly. (Add reference, not service reference ).

Then, in Program. cs, the using namespace

Using System. ServiceModel;

(2) Prepare a service agreement

Service agreements are the most important part of metadata (Data agreements may also exist). protocol interfaces are jointly held by servers and clients. Clients rely on agreements to create channels, then, the client does not know how to call the Protocol method and method implementation on the channel. The client only knows the method signature and return value (that is, the interface ).

 

We can copy the service agreements defined on the server. Note that only interfaces can be moved, and implementations cannot be moved. This is what the server can have.

 

We are all very familiar with service agreements. It is written after the Program class.

    [ServiceContract]      public interface IHelloWCF      {          [OperationContract]          string HelloWCF();      }  

OK. The first part of the metadata is complete, and the other two parts are provided in the Code.

(3) channel factory debut

System. ServiceModel provides a class named ChannelFactory <>, which accepts the service agreement interface as a generic parameter, so that the new instance is called the channel factory of the service agreement XXX. As the name suggests, this factory is dedicated to the production channel, which is the communication channel established between the server endpoint and the client endpoint. Since this channel is established using a service agreement, you can call the operation of this service agreement on this channel.

The constructor of the channel factory class accepts some heavy-duty parameters that provide the channel factory with information about the server end point, including the address and binding, which is the other two parts of the metadata. Let's prepare the two.

It can also be called an endpoint address, which is actually a URI. We also have a dedicated service class to represent it, called EndpointAddress. We have a new instance:

EndpointAddress address = new EndpointAddress("http://localhost/IISService/HelloWCFService.svc"); 

Only one String parameter is accepted, that is, the URI address. Here I use the address of the IIS service established in article 3.

Binding. Our server end point requires wsHttpBinding. We can also use the service class to indicate it, which is called WSHttpBinding. We have a new instance:

WSHttpBinding binding = WSHttpBinding ();

 

You can use a constructor with null parameters.

 

All right, the other two items of metadata are also ready. Now let's make a debut at the Channel factory. We have a new instance and use the service agreement interface just created as a generic parameter, use the address and bound object created above as the constructor parameter:

ChannelFactory <IHelloWCF> factory = ChannelFactory <IHelloWCF> (binding, address );

With the factory, we will start to produce a channel by executing the CreateChannel method of the channel factory. Since the factory was created using our protocol interface, the channel produced also implements this interface. We can directly use the Protocol interface to declare its return value.

 

IHelloWCF channel = factory.CreateChannel();  

 

Now that the channel has been opened, we can call the Protocol Method on this channel.

string result = channel.HelloWCF();  

Then, we output the results, just like the client program we used previously.

 Console.WriteLine(result);  Console.ReadLine();  Console.WriteLine(result);  Console.ReadLine(); 

Yahoo !, We didn't use the metadata exchange function. With the hand-drawn metadata and code, the client-to-server communication was completed. We can still do this without service references or configuration files. Although the entire process is not completely clear, I have understood the communication process.

All code of Program. cs

    using System;      using System.Collections.Generic;      using System.Linq;      using System.Text;      using System.ServiceModel;            namespace ConsoleClient      {          class Program          {              static void Main(string[] args)              {                  EndpointAddress address = new EndpointAddress("http://localhost/IISService/HelloWCFService.svc");                  WSHttpBinding binding = new WSHttpBinding();                        ChannelFactory<IHelloWCF> factory = new ChannelFactory<IHelloWCF>(binding, address);                        IHelloWCF channel = factory.CreateChannel();                        string result = channel.HelloWCF();                        Console.WriteLine(result);                  Console.ReadLine();              }          }                [ServiceContract]          public interface IHelloWCF          {              [OperationContract]              string HelloWCF();          }      }  

4. expand a little bit.

It has been quite successful. let's expand it a little more. Remember the IHelloWCFChannel interface we saw in reference. cs, which was generated by referencing the service earlier? We searched for the solution and didn't find any place to use it? Is it useless? Of course not. Let's study it now.

 

The hand-drawn program above can open the channel and call the service. However, we recall that the client we created through the service reference provided a Close () method to Close the service connection. If we use this method, we should also close the channel. Although the client closes the channel, it is always a good habit to close it after using the channel.

 

But how to implement it? We found that the channel cannot provide a method to disable it. This is because the channel object declared using the IHelloWCF interface can only provide the method specified by the interface. In fact, the channel object itself provides the closing method, but it is blocked by the interface declaration we display. The channel has actually implemented another interface called IClientChannel, this interface provides methods to open and close a channel. If you want to call this function, you only need to forcibly convert the channel object to the IClientChannel interface type:

But how to implement it? We found that the channel cannot provide a method to disable it. This is because the channel object declared using the IHelloWCF interface can only provide the method specified by the interface. In fact, the channel object itself provides the closing method, but it is blocked by the interface declaration we display. The channel has actually implemented another interface called IClientChannel, this interface provides methods to open and close a channel. If you want to call this function, you only need to forcibly convert the channel object to the IClientChannel interface type:

(IClientChannel) channel). Close ();

However, this is not natural and elegant enough, and forced conversion is always confusing. Can I keep the IHelloWCF object type and allow it to provide the closing method? Of course. Let's create another interface that implements both the IHelloWCF service agreement interface and the IClientChannel interface, and use this new interface to go to the new channel factory, in this way, can I use the service operations in IHelloWCF and the method to close the channel in IClientChannel at the same time?

 

 

First, create this new interface. This interface only Concatenates the service agreement interface and IClientChannel. It has no other members and is an empty interface.

 

 

 public interface IHelloWCFChannel : IHelloWCF, IClientChannel  {     }

Then, modify the previous statement for creating a channel factory and use the new interface name as a generic parameter to create a new channel factory.

ChannelFactory<IHelloWCFChannel> factory = new ChannelFactory<IHelloWCFChannel>(binding, address);

Modify the object declaration type of the production channel method and use the new interface type declaration:

IHelloWCFChannel channel = factory.CreateChannel();  

Finally, after calling the service operation, we can directly call the method to close the channel:

channel.Close();  

Source code of the modified program. cs:

    using System;      using System.Collections.Generic;      using System.Linq;      using System.Text;      using System.ServiceModel;            namespace ConsoleClient      {          class Program          {              static void Main(string[] args)              {                  EndpointAddress address = new EndpointAddress("http://localhost/IISService/HelloWCFService.svc");                  WSHttpBinding binding = new WSHttpBinding();                        ChannelFactory<IHelloWCFChannel> factory = new ChannelFactory<IHelloWCFChannel>(binding, address);                        IHelloWCFChannel channel = factory.CreateChannel();                        string result = channel.HelloWCF();                        channel.Close();                        Console.WriteLine(result);                  Console.ReadLine();              }          }                [ServiceContract]          public interface IHelloWCF          {              [OperationContract]              string HelloWCF();          }                public interface IHelloWCFChannel : IHelloWCF, IClientChannel          {                     }                }  


Now, we understand what the seemingly useless interface is in the service reference. However, the implementation in service references is different from ours. It uses a class called ClientBase <> for channel communication. We will expand it later.

5. Summary

Today's research is a little deeper. It doesn't matter if you don't fully understand it. You just have a concept in mind.

We use the hand-drawn code method to achieve communication between the client and the server, without the use of metadata exchange tools. This gives us a better understanding of the communication between the server and the client. In fact, the so-called metadata exchange is to let us get such a simple programming model. The things behind it are very similar to what we are doing today. Imagine, product-level services may have many protocol interfaces and many endpoints. It is impossible or effort-consuming to manually provide them on the client. Therefore, metadata exchange is meaningful, we should learn how to use it, and continue to master the way to control metadata exchange tools in the future.

 

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.