初识.net WCF

WCF, Windows Communication Foundation 是.net一个基于服务的通信框架。
我所理解的基于服务,是指采用客户端-服务端模式提供的服务。

WCF的前身应该是web service,WCF作为继承者,除了web service的功能外,提供了更多的配置选项。
服务端与客户端之间的交互,不仅仅是HTTP,可以是其他的通信机制,比如MSMQ。

与web service类似,WCF的创建,也比较依赖vs工具进行搭建,自己做不是说做不了,而是麻烦很多。
在这里简单记录一个WCF服务端和客户端的例子。

服务端

WCF服务端提供各种功能供客户端调用/通信。
wcf服务端分为两部分,服务内容,和宿主。

WCF服务提供内容简单认为有ABC三部分,即

  • A, Address,服务提供地址
  • B, Binding, 服务提供的的协议
  • C, Contract,服务内容格式

服务内容

web service的服务,一般来说是一个标记有WebServiceAttribute的类;
而WCF的服务,是一个带有ServiceContractAttribute接口的类库,这也就是所谓的C-Contract,它定义的是服务应用侧的数据格式,服务接口。

接口对应的实现,则没有特殊的标记。

接口

这里是用的MS官网上的WCF服务作为例子

 [ServiceContract]
    public interface ICalculator
    {
        [OperationContract]
        double Add(double n1, double n2);

        [OperationContract]
        double Subtract(double n1, double n2);

        [OperationContract]
        double Multiply(double n1, double n2);

        [OperationContract]
        double Divide(double n1, double n2);
    }

实现

接口的实现没有特别的属性注释,正常实现接口即可


    public class CalculatorService : ICalculator
    {
        public double Add(double n1, double n2)
        {
            double result = n1 + n2;
            Console.WriteLine("Received Add({0},{1})", n1, n2);
            // Code added to write output to the console window.
            Console.WriteLine("Return: {0}", result);
            return result;
        }

        public double Subtract(double n1, double n2)
        {
            double result = n1 - n2;
            Console.WriteLine("Received Subtract({0},{1})", n1, n2);
            Console.WriteLine("Return: {0}", result);
            return result;
        }

        public double Multiply(double n1, double n2)
        {
            double result = n1 * n2;
            Console.WriteLine("Received Multiply({0},{1})", n1, n2);
            Console.WriteLine("Return: {0}", result);
            return result;
        }

        public double Divide(double n1, double n2)
        {
            double result = n1 / n2;
            Console.WriteLine("Received Divide({0},{1})", n1, n2);
            Console.WriteLine("Return: {0}", result);
            return result;
        }
    }

配置

对应的wcf在配置文件app.config中的配置。

这里指定了上面提到的ABC,不过在容器中,同样也需要进行相同的配置。

<system.serviceModel>
    <services>
      <service name="GettingStartedLib.CalculatorService">
        <host>
          <baseAddresses>
            <add baseAddress = "http://localhost:18000/GettingStarted/CalculatorService" />
          </baseAddresses>
        </host>
        <endpoint address="" binding="wsHttpBinding" contract="GettingStartedLib.ICalculator">
          <identity>
            <dns value="localhost" />
          </identity>
        </endpoint>
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior>
          <serviceMetadata httpGetEnabled="True" httpsGetEnabled="True" />
          <serviceDebug includeExceptionDetailInFaults="False" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>

宿主

宿主
Web应用或者Console应用都可以作为宿主,这里以控制台应用为例。


        private static void Main(string[] args)
        { // Step 1 Create a URI to serve as the base address.
            Uri baseAddress = new Uri("http://localhost:60002/GettingStarted/");

            // Step 2 Create a ServiceHost instance
            ServiceHost selfHost = new ServiceHost(typeof(CalculatorService), baseAddress);

            try
            {
                // Step 3 Add a service endpoint.
                selfHost.AddServiceEndpoint(typeof(ICalculator), new WSHttpBinding(), "CalculatorService");

                // Step 4 Enable metadata exchange.
                ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
                smb.HttpGetEnabled = true;
                selfHost.Description.Behaviors.Add(smb);

                // Step 5 Start the service.
                selfHost.Open();
                Console.WriteLine("The service is ready.");
                Console.WriteLine("Press <ENTER> to terminate service.");
                Console.WriteLine();
                Console.ReadLine();

                // Close the ServiceHostBase to shutdown the service.
                selfHost.Close();
            }
            catch (CommunicationException ce)
            {
                Console.WriteLine("An exception occurred: {0}", ce.Message);
                selfHost.Abort();
            }
        }
  1. 创建一个Uri,这个地址就是这个服务的基础地址
  2. 创建一个SelfHost,绑定到该地址上,则该服务在该地址上运行
  3. 创建一个endpointendpoint是服务的触点,个人把他理解为例如网站中网页的地址,真正用于交互的是endpointendpoint指明了该服务提供的具体服务类型ICalculator(从而了解该服务包含哪些方法),服务的通信协议、又叫binding,服务的访问地址CalculatorService,该地址叠加在基地址Uri上。
  4. 增加behaviourbehaviour定义了服务提供的一些功能,再实例中提使能了metatdata的获取
  5. 启动宿主机

启动后,就能在指定地址http://localhost:60002/GettingStarted/该服务了。
不过为了通过程序访问,还需要搭建客户端

客户端

WCCF的客户端搭建,依赖vs自带的功能,或者使用微软的svcutil.exe工具。

  1. 新建一个console应用
  2. 增加System.ServiceModel引用
  3. 在Solution窗口中,右键点击该项目,在弹出菜单中选择Add->Service Reference
  4. 在弹出窗口中的地址中,输入服务端的地址,点击Go开始解析
  5. 解析完毕,可以看到刚刚建立的CalculatorService服务endpoint,点击OK即可引入该服务
  6. 引入服务后,就可以像本地调用一样,创建该服务实力,调用服务方法了。方法内部包含了实际的远程调用过程,不过这些对调用者是透明的。
private static void Main(string[] args)
        {
            //Step 1: Create an instance of the WCF proxy.
            CalculatorClient client = new CalculatorClient();

            // Step 2: Call the service operations.
            // Call the Add service operation.
            double value1 = 100.00D;
            double value2 = 15.99D;
            double result = client.Add(value1, value2);
            Console.WriteLine("Add({0},{1}) = {2}", value1, value2, result);

            // Call the Subtract service operation.
            value1 = 145.00D;
            value2 = 76.54D;
            result = client.Subtract(value1, value2);
            Console.WriteLine("Subtract({0},{1}) = {2}", value1, value2, result);

            // Call the Multiply service operation.
            value1 = 9.00D;
            value2 = 81.25D;
            result = client.Multiply(value1, value2);
            Console.WriteLine("Multiply({0},{1}) = {2}", value1, value2, result);

            // Call the Divide service operation.
            value1 = 22.00D;
            value2 = 7.00D;
            result = client.Divide(value1, value2);
            Console.WriteLine("Divide({0},{1}) = {2}", value1, value2, result);

            //Step 3: Closing the client gracefully closes the connection and cleans up resources.
            client.Close();

            Console.ReadLine();
        }

总结

简单的使用WCF与web service类似,但是WCF包含了很多高级功能,如异步、跨平台、多种通信方式、安全认证等等,这些是WCF强大的地方。

posted @ 2020-03-31 20:53  mosakashaka  阅读(384)  评论(0编辑  收藏  举报