WCF的服务不能孤立地存在,需要寄宿于一个运行着的进程中,我们把承载WCF服务的进程称为宿主,为服务指定宿主的过程称为服务寄宿(Service Hosting)。
我们要用WCF来实现一个远程调用计算的方法
步骤一:构建整个解决方案
通过VS 2008创建一个空白的解决方案,添加如下四个项目。项目的类型、承载的功能和相互引用关系如下,整个项目在VS下的结构如图2所示。
- Contracts:一个类库项目,定义服务契约(Service Contract),添加引用System.ServiceMode程序集;
- Services:一个类库项目,提供对WCF服务的实现。定义在该项目中的所有WCF服务实现了定义在Contracts中相应的服务契约,所以Services具有对Contracts项目的引用;
- Hosting:一个控制台(Console)应用,实现对定义在Services项目中的服务的寄宿,该项目须要同时引用Contracts和Services两个项目和System.ServiceMode程序集;
- Application:一个控制台应用模拟服务的客户端,该项目引用System.ServiceMode程序集。
步骤二:创建服务契约
先在Contracts定义一个接口 IOperation
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.ServiceModel; namespace WcfServices.Contracts { [ServiceContract(Name = "OperationService")] public interface IOperation { [OperationContract] double Add(double x, double y); } }
步骤三:创建服务
在Services层来实现这个接口
当服务契约成功创建时,我们需要通过实现服务契约来创建具体的WCF服务。WCF服务OperationService定义在Services项目中,实现了服务契约接口IOperation,实现了所有的服务操作。OperationService定义如下:using System; using System.Collections.Generic; using System.Linq; using System.Text; using WcfServices.Contracts; namespace WcfServices.Services { public class OperationService:IOperation { #region IOperation 成员 public double Add(double x, double y) { return x + y; } #endregion } }
步骤四:通过自我寄宿的方式寄宿服务
WCF服务需要依存一个运行着的进程(宿主),服务寄宿就是为服务指定一个宿主的过程。WCF是一个基于消息的通信框架,采用基于终结点(Endpoint)的通信手段。终结点由地址(Address)、绑定(Binding)和契约(Contract)三要素组成,如图3所示。由于三要素应为首字母分别为ABC,所以就有了易于记忆的公式:Endpoint = ABC。一个终结包含了实现通信所必需的所有信息,我们可以这样认识终结点的ABC:
- 地址(Address):地址决定了服务的位置,解决了服务寻址的问题,
- 绑定(Binding):绑定实现了通信的所有细节,包括网络传输、消息编码,以及其他为实现某种功能(比如安全、可靠传输、事务等)对消息进行的相应处理。WCF中具有一系列的系统定义绑定,比如BasicHttpBinding、WsHttpBinding、NetTcpBinding等
- 契约(Contract):契约是对服务操作的抽象,也是对消息交换模式以及消息结构的定义。
服务寄宿的目的就是开启一个进程,为WCF服务提供一个运行的环境。通过为服务添加一个或多个终结点,使之暴露给潜给的服务消费者。服务消费者最终通过相 匹配的终结点对该服务进行调用。我们可以完全通过代码的方式完成所有的服务寄宿工作,下面的代码体现了通过一个控制台应用对 OperationService的寄宿
using System; using System.Collections.Generic; using System.Linq; using System.Text; using WcfServices.Services; using WcfServices.Contracts; using System.ServiceModel; using System.ServiceModel.Description; namespace WcfServices.Hosting { class Program { static void Main(string[] args) { using (ServiceHost host = new ServiceHost(typeof(OperationService))) { host.Opened += delegate { Console.WriteLine("OperationService已经启动,按任意键终止服务!"); }; host.Open(); Console.Read(); } } } }
然后我门要写一些配置信息 在Hosting下添加一个应用程序配置文件
代码如下 也可以通过 工具--wcf服务配置工具来生成 (见这里 )<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="NewBehavior">
<serviceMetadata httpGetEnabled="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service behaviorConfiguration="NewBehavior" name="WcfServices.Services.OperationService">
<endpoint address="" binding="basicHttpBinding" bindingConfiguration=""
contract="WcfServices.Contracts.IOperation" />
<host>
<baseAddresses>
<add baseAddress="http://127.0.0.1:9999/OperationService" />
</baseAddresses>
</host>
</service>
</services>
</system.serviceModel>
</configuration>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using WcfServices.Services;
using WcfServices.Contracts;
using System.ServiceModel;
using System.ServiceModel.Description;
namespace WcfServices.Hosting
{
class Program
{
static void Main(string[] args)
{
using (ServiceHost host = new ServiceHost(typeof(OperationService)))
{
host.Opened += delegate
{
Console.WriteLine("OperationService已经启动,按任意键终止服务!");
};
host.Open();
Console.Read();
}
}
}
}按F5启动测试
服务启动了?我们来测试下 在浏览器中输入我们配置的baseAddress地址 http://127.0.0.1:9999/OperationService
-
出现下面的图示 则OK(有个配置节点决定是否显示元数据 后面在讲)
步骤五:创建客户端调用服务
同样在Application里添加配置文件
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<client>
<endpoint address="http://127.0.0.1:9999/OperationService"
binding="basicHttpBinding"
contract="WcfServices.Contracts.IOperation"
name="OperationService"></endpoint>
</client>
</system.serviceModel>
</configuration>
Program.cs 代码
-
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using WcfServices.Contracts;
using System.IO;
namespace WcfServices.Client
{
class Program
{
static void Main(string[] args)
{
using (ChannelFactory<IOperation> channelFactory = new ChannelFactory<IOperation>("OperationService"))
{
IOperation proxy = channelFactory.CreateChannel();
using (proxy as IDisposable)
{
Console.WriteLine("x + y = {2} when x = {0} and y = {1}", 1, 2, proxy.Add(1, 2));
}
}
Console.Read();
}
}
}OK 先开启服务端 对Hosting 点右键 在点调试 选启动新实例 然后在Application 也是一样操作
调用成功! 附带源代码