最近通过研读《WCF技术剖析》来学习WCF框架。现就一个简单的WCF程序以及寄宿问题来做个学习笔记。
WCF是一个基于消息的通信框架,采用基于终结点的通信手段。终结点由地址(Address),绑定(Binding)和契约(Contract)三要素构成。
首先我们构建一个简单的解决方案,包含如下项目:
1、Contracts 定义服务契约。
2、Services 实现Contracts中定义的服务契约接口。
3、Hosting 实现Services的服务的寄宿(服务端 控制台程序)。
4、Client 客户端(控制台程序) 调用WCF服务。
解决方案如图:
一、Contracts程序集 我们新建一ICalculator.cs接口文件,定义服务契约:
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接口 实现服务:
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 得到结果
学习到此(继续学习)