最近通过研读《WCF技术剖析》来学习WCF框架。现就一个简单的WCF程序以及寄宿问题来做个学习笔记。

WCF是一个基于消息的通信框架,采用基于终结点的通信手段。终结点由地址(Address),绑定(Binding)和契约(Contract)三要素构成。

首先我们构建一个简单的解决方案,包含如下项目:

1、Contracts  定义服务契约。

2、Services    实现Contracts中定义的服务契约接口。

3、Hosting     实现Services的服务的寄宿(服务端 控制台程序)。

4、Client        客户端(控制台程序) 调用WCF服务。

解决方案如图:

一、Contracts程序集 我们新建一ICalculator.cs接口文件,定义服务契约:

View Code
using System;
using System.Collections.Generic;
using System.Text;
using System.ServiceModel;

namespace Contracts
{
    [ServiceContract(Name="CalculatorService", Namespace="http://service.com")]
    public interface ICalculator
    {
        [OperationContract]
        double Add(double x, double y);

        [OperationContract]
        double Subtract(double x, double y);
    }
}

二、Services程序集  新建一CalculatorService.cs类 继承ICalculator接口 实现服务:

View Code
using System;
using System.Collections.Generic;
using System.Text;
using System.ServiceModel;
using Contracts;

namespace Services
{
    public class CalculatorService:ICalculator
    {
        public double Add(double x, double y)
        {
            return x + y;
        }

        public double Subtract(double x, double y)
        {
            return x - y;
        }
    }
}

三、Hosting控制台程序 实现服务的寄宿:

实现服务寄宿的方法包括:自我寄宿和IIS寄宿。

自我寄宿:1、完全硬编码方式实现自我寄宿 2、通过配置文件进行自我寄宿。

1、完全硬编码方式实现自我寄宿:(例子:URI中的协议采用http协议)

using (ServiceHost host = new ServiceHost(typeof(CalculatorService)))
            {
                host.AddServiceEndpoint(typeof(ICalculator), new WSHttpBinding(), "http://localhost:9999/calculatorservice");
                if (host.Description.Behaviors.Find<ServiceMetadataBehavior>() == null)
                {
                    ServiceMetadataBehavior behavitor = new ServiceMetadataBehavior();
                    behavitor.HttpGetEnabled = true;
                    behavitor.HttpGetUrl = new Uri("http://localhost:9999/calculatorservice/metadata");
                    host.Description.Behaviors.Add(behavitor);
                    host.Opened += delegate
                    {
                        Console.WriteLine("服务已经启动,按任意键终止服务!");
                    };
                    host.Open();
                    Console.Read();
                }
            }

2、通过配置文件实现自我寄宿

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.serviceModel>
    <!--http端口配置开始-->
    <!--<behaviors>
      <serviceBehaviors>
        <behavior name="metadataBehavior">
          <serviceMetadata httpGetEnabled="True" httpGetUrl="http://127.0.0.1:9998/calculatorservice/metadata"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <services>
      <service behaviorConfiguration="metadataBehavior" name="Services.CalculatorService">
        <endpoint address="http://127.0.0.1:9998/calculatorservice" binding="wsHttpBinding" contract="Contracts.ICalculator" />
      </service>
    </services>-->
    <!--http端口配置结束-->
    <!--TCP端口服务配置开始-->
    <services>
      <service  name="Services.CalculatorService">
        <endpoint address="CalculatorService" binding="netTcpBinding" contract="Contracts.ICalculator" />
        <host>
          <baseAddresses>
            <add baseAddress="net.tcp://127.0.0.1:8888/myservices"/>
          </baseAddresses>
        </host>
      </service>
    </services>
    <!--TCP端口服务配置结束-->
  </system.serviceModel>
</configuration>

这样执行 控制台程序 则会启动2个服务 一个为http协议的 一个为tcp协议的。

IIS寄宿:

实现IIS寄宿需要2个步骤 1、创建WCF服务的.svc文件 2、创建IIS虚拟目录。

1、创建.SVC文件 在Sercices程序集下 新建一.SVC文件 写入如下代码:

<%@ServiceHost Service="Services.CalculatorService" %>

2、创建虚拟目录 这里我把Services程序集作为虚拟目录(WcfService)的文件夹,新建web.config文件 写入配置代码

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.serviceModel>
    <behaviors>
      <serviceBehaviors>
        <behavior name="metadataBehavior">
          <serviceMetadata httpGetEnabled="true"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <services>
      <service behaviorConfiguration="metadataBehavior" name="Services.CalculatorService">
        <host>
        <baseAddresses>
          <add baseAddress="http://localhost:9009/"/>
        </baseAddresses>
        </host>
        <endpoint address="calculatorservice" binding="wsHttpBinding" contract="Contracts.ICalculator" />
      </service>
    </services>
  </system.serviceModel>
</configuration>

寄宿完成。上面的硬编码方式和IIS寄宿模式下 可以分别通过链接区访问元数据:

1、http://localhost:9999/calculatorservice/metadata 

2、http://127.0.0.1/WcfService/CalculatorService.svc/calculatorservice

四、Client(控制台程序) 服务调用,这里会创建2个不同的信息通道 来实现2个不同服务的代理类;一个是HTTP的 一个是tcp的;还有一个是手动增加服务引用 即IIS寄宿的服务,然后打印出调用不同服务的结果。

static void Main(string[] args)
        {
            try
            {
                ChannelFactory<ICalculator> channelFactory = new ChannelFactory<ICalculator>(new WSHttpBinding(), "http://localhost:9999/calculatorservice");
                ICalculator proxy = channelFactory.CreateChannel();

                ChannelFactory<ICalculator> channelFactorys = new ChannelFactory<ICalculator>(new NetTcpBinding(), "net.tcp://127.0.0.1:8888/myservices/CalculatorService");
                ICalculator proxys = channelFactorys.CreateChannel();

                CalculatorServiceClient proxyss = new CalculatorServiceClient();

                Console.WriteLine("编码方式自我寄宿:http://localhost:9999/calculatorservice");
                Console.WriteLine("\r");
                Console.WriteLine("x+y={2} when x={0} and y={1}", 1, 2, proxy.Add(1, 2));
                Console.WriteLine("x-y={2} when x={0} and y={1}", 1, 2, proxy.Subtract(1, 2));

                Console.WriteLine("\r");
                Console.WriteLine("配置方式自我寄宿:net.tcp://127.0.0.1:8888/myservices/CalculatorService");
                Console.WriteLine("\r");
                Console.WriteLine("x+y={2} when x={0} and y={1}", 1, 2, proxys.Add(1, 2));
                Console.WriteLine("x-y={2} when x={0} and y={1}", 1, 2, proxys.Subtract(1, 2));

                Console.WriteLine("\r");
                Console.WriteLine("IIS寄宿手动添加服务引用:http://127.0.0.1/WcfService/CalculatorService.svc/calculatorservice");
                Console.WriteLine("\r");
                Console.WriteLine("x+y={2} when x={0} and y={1}", 1, 2, proxyss.Add(1, 2));
                Console.WriteLine("x-y={2} when x={0} and y={1}", 1, 2, proxyss.Subtract(1, 2));
            }
            catch (Exception ex)
            { 
                Console.WriteLine(ex.Message);
            }
        }

执行Client 得到结果

《WCF技术剖析》学习笔记之创建简单的WCF程序以及服务寄宿

 学习到此(继续学习)

 附上源码

相关文章: