WCF学习心得----(三)服务承载
这一章节花费了好长的时间才整理个大概,主要原因是初次接触这个东西,在做练习实践的过程中,遇到了很多的问题,有些问题到目前还没有得以解决。所以在这一章节中,有一个承载是没有例子的。仍在努力解决所在的问题,后续会把例子给补上的。好了,进入正题。
要变为活动状态,服务必须承载于创建它并控制它的上下文和生存周期的运行环境中。WCF有以下三种承载方式:在IIS中承载、在Windows进程激活(WAS)中承载、在托管应用程序中承载(自承载)。下面就分别对这三种承载方式,一一介绍。
1. 在IIS中承载
1.1 概述
WCF可以方便的通过IIS承载,此承载模型与ASP.NET和ASP.NET Web Service使用的模型类似,都是通过HTTP协议进行激活和网络通信的。
WCF可以在Windows XP SP2上的IIS5.1、Windows Server2003上的IIS 6.0、Windows 7和Windows Server 2008的IIS 7.0上承载。
1.2 优点
1) 可以向处理其他任何类型的IIS应用程序一样,部署和管理IIS中承载的WCF服务。
2) IIS提供进程激活、运行状态管理和回收功能以提高承载的应用程序的可靠性。
3) 像ASP.NET一样,ASP.NET中承载的WCF服务可以利用ASP.NET共享宿主模型,在此模型中,多个应用程序驻留在一个公共辅助进程中以提高服务器密度和可伸缩性。
4) IIS中承载的WCF服务与ASP.NET2.0使用相同的动态编译模型,该模型简化了承载服务的开发和部署。
5) IIS承载WCF服务时,IIS5.1和IIS6.0仅限于HTTP通信。
1.3 部署IIS承载WCF服务示例
1.3.1 确保正确安装和注册IIS、WCF、WCF HTTP激活组件。
方法如下:控制面板—>所有面板项—>程序和功能—>打开或关闭Windows功能—>
将如上图所示的项勾选即可。
当然除了在打开或关闭Windows功能面板里边勾选之外,我们还可以通过命令在dos窗口里激活组件,由于操作起来不如直接在windows功能里勾选方便,所以这里就不再列出相应的激活命令了,有兴趣的朋友可以下去自己在网上搜一下。
1.3.2 具体代码演示
1.3.2.1 新建WCFService客户端,WCF服务程序
1.3.2.1.1目录结构如下:
1.3.2.1.2 在ICalculatorService.cs中代码如下,该文件主要用来定制服务的协定
[ServiceContract(Namespace=”WCFService”)] public interface ICalculatorService { [OperationContract] double Add(double n1, double n2); [OperationContract] double Subtract(double n1, double n2); [OperationContract] double Mutiply(double n1, double n2); [OperationContract] double Devide(double n1, double n2); }
1.3.2.1.3 CalculatorService.svc.cs文件中代码如下,该文件主要实现了服务定制的接口
public class CalculatorService : ICalculatorService { public double Add(double n1, double n2) { return n1 + n2; } public double Subtract(double n1, double n2) { return n1 - n2; } public double Mutiply(double n1, double n2) { return n1 * n2; } public double Devide(double n1, double n2) { return n1 / n2; } }
1.3.2.1.4 Web.config文件中代码如下,该文件主要定制服务的配置
<?xml version="1.0" encoding="utf-8"?> <configuration> <system.web> <compilation debug="true" targetFramework="4.0" /> </system.web> <system.serviceModel> <services> //配置服务 <service name="WCFService.CalculatorService" behaviorConfiguration="CalculatorServiceBeheavior"> //配置服务的根节点 <endpoint address="" binding="wsHttpBinding" contract="WCFService.ICalculatorService"/> //配置元数据的根节点 <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/> </service> </services> <behaviors> <serviceBehaviors> //配置服务的行为,允许获取元数据 <behavior name="CalculatorServiceBeheavior"> <serviceMetadata httpGetEnabled="true"/> <serviceDebug includeExceptionDetailInFaults="false"/> </behavior> </serviceBehaviors> </behaviors> <serviceHostingEnvironment multipleSiteBindingsEnabled="true" /> </system.serviceModel> <system.webServer> <modules runAllManagedModulesForAllRequests="true"/> </system.webServer> </configuration>
1.3.2.2 在IIS中创建网站,将该服务端生成的如下图红框圈住的文件拷贝至网站虚拟目录对应的物理路径下
然后发布在浏览器中观看如下图:
这时还需要留意,浏览器中的url,如下:
1.3.2.3 使用Svcutil.exe工具生成客户端调用类和配置文件
1.3.2.3.1打开命令行提示符工具,输入一下命令,将目录定位到Svcutil.exe所在的目录。
Svcutil.exe目录一般位于C:Program FilesMicrosoft SDKsWindowsv7.1Bin文件夹下,所以命令如下:
Cd C:Program FilesMicrosoft SDKsWindowsv7.1Bin
1.3.2.3.2 定位到该文件下之后,继续键入以下命令:
Svcutil.exe /out:D:CalculatorClient.cs /config:D:App.config
http://localhost:116/CalculatorService.svc
备注:
Svcutil工具生成客户端使用类有固定的语法参数,下面仅列出了该文所需的一些参数,至于其他的参数以后可能还会涉及到,有兴趣的话可以去msdn上了解一些。
1) “/out:”后跟生成文件的存放路径+文件名+.cs
2) “/config:”后跟生成文件的存放路径+app.config
3) http://.... 为服务的地址,承载服务的应用程序运行起来时,Svcutil.exe通过该服务地址,生成下载客户段使用类,该地址跟配置文件中的<host>节点下的地址是一致的。
1.3.2.4 新建WCF客户端应用程序
1.3.2.4.1将1.3.2.3.中生成的CalculatorClient.cs文件和App.config文件添加到项目中
项目结构图如下:
1.3.2.4.2 在Program.cs文件中使用客户端调用类,调用服务端的服务
代码如下:
class Program { static void Main(string[] args) { CalculatorServiceClient calculatorClient = new CalculatorServiceClient(); Console.WriteLine("{0}+{1}={2}", 1.2, 2.3, calculatorClient.Add(1.2, 2.3)); Console.WriteLine("{0}-{1}={2}", 2.3, 3.4, calculatorClient.Subtract(2.3, 3.4)); Console.WriteLine("{0}*{1}={2}", 3.4, 4.5, calculatorClient.Mutiply(3.4, 4.5)); Console.WriteLine("{0}/{1}={2}", 4.5, 3.0, calculatorClient.Devide(4.5, 3.0)); Console.WriteLine("OK! That's all!"); Console.Read(); } }
1.3.2.5 运行客户端程序WCFClient
效果如图:
2.在Windows进程激活服务(WAS)中承载
2.1 概述
Windows进程激活服务(WAS)管理辅助进程的激活和生存周期,该辅助进程包含WCF服务的应用程序。WAS进程模型通过移除对HTTP的依赖性使HTTP服务器的IIS6.0进程模型通用化,允许WCF服务在宿主环境中同时使用HTTP和非HTTP协议(例:NET.TCP),该宿主环境支持基于消息的激活并提供在给定计算机上承载大量应用程序的能力。
2.2 优点
1) 基于消息的应用程序激活和辅助进程应用程序会动态的启动和停止,以响应使用HTTP和非HTTP网络协议送达的传入工作项
2) 可靠的应用程序和辅助进程回收可以使应用程序保持良好的运行状况
3) 集中的应用程序配置和管理
4) 允许应用程序利用IIS进程模型,而无需完全IIS安装部署的需求量。
2.3 在WA中承载WCF服务示例
2.3.1 确保正确的安装了所需的WCF激活组件
方法如下:方法如下:控制面板—>所有面板项—>程序和功能—>打开或关闭Windows功能—>
将如上图所示的项勾选即可。另有通过命令激活的方法,这里不作详解。
2.3.2 代码演示
略(待续)
3.在托管的应用程序中承载(自承载)
3.1 概述
服务可以承载于任何.NET Framework应用程序中。
自承载服务时最灵活的宿主选项,因为此服务部署所需要的基础结构最少,但是该服务也是最不可靠的宿主选项。
3.2 优点
服务部署所需基础结构最少,是最为灵活的宿主选项
3.3 在托管的应用程序中承载WCF服务示例
3.3.1 新建控制台应用程序命名为ZWCFService,作为服务的承载程序,主要的目录结构如下:
具体的编码实现如下,编码实现之后要确保该程序运行起来,这样才能够获取到该服务
3.3.1.1 在Program.cs中编码如下:
class Program { static void Main(string[] args) { using(ServiceHost serviceHost=new ServiceHost (typeof(CalculatorService))) { serviceHost.Open(); Console.WriteLine("This service is ok!"); Console.WriteLine("Press any key to teiminate the service!"); Console.WriteLine(); Console.Read(); } } } [ServiceContract(Namespace="http://ZWCFService")] public interface ICalculatorService { [OperationContract] double Add(double n1, double n2); [OperationContract] double Subtract(double n1, double n2); [OperationContract] double Mutiply(double n1, double n2); [OperationContract] double Devide(double n1, double n2); } public class CalculatorService : ICalculatorService { public double Add(double n1, double n2) { double result = n1 + n2; Console.WriteLine("{0}+{1}={2}", n1, n2, result); return result; } public double Subtract(double n1, double n2) { double result = n1 - n2; Console.WriteLine("{0}-{1}={2}", n1, n2, result); return result; } public double Mutiply(double n1, double n2) { double result = n1 * n2; Console.WriteLine("{0}*{1}={2}", n1, n2, result); return result; } public double Devide(double n1, double n2) { double result = n1 / n2; Console.WriteLine("{0}/{1}={2}", n1, n2, result); return result; } }
3.3.1.2 App.config配置文件中代码如下:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<services>
<service name="ZWCFService.CalculatorService" behaviorConfiguration="CalculatorServiceBeheavior">
<host>
<baseAddresses>
<add baseAddress="http://localhost:8000/ZWCFService/CalculatorService"/>
</baseAddresses>
</host>
<endpoint address="" binding="wsHttpBinding" contract="ZWCFService.ICalculatorService"/>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="CalculatorServiceBeheavior">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
3.3.2 使用Svcutil.exe工具生成CalculatorClinet类文件和app配置文件
3.3.2.1 打开命令行提示符工具,输入一下命令,将目录定位到Svcutil.exe所在的目录。
Svcutil.exe目录一般位于C:Program FilesMicrosoft SDKsWindowsv7.1Bin文件夹下,所以命令如下:
Cd C:Program FilesMicrosoft SDKsWindowsv7.1Bin
3.3.2.2 定位到该文件下之后,继续键入以下命令:
Svcutil.exe /out:C:CalculatorClient.cs /config:C:App.config
http://localhost:8000/ZWCFService/CalculatorService
备注:
Svcutil工具生成客户端使用类有固定的语法参数,下面仅列出了该文所需的一些参数,至于其他的参数以后可能还会涉及到,有兴趣的话可以去msdn上了解一些。
1) “/out:”后跟生成文件的存放路径+文件名+.cs
2) “/config:”后跟生成文件的存放路径+app.config
3) http://.... 为服务的地址,承载服务的应用程序运行起来时,Svcutil.exe通过该服务地址,生成下载客户段使用类,该地址跟配置文件中的<host>节点下的地址是一致的。
3.3.3 新建一个名为ZCWFServiceClient客户端应用程序(控制台或winform应用程序均可)
3.3.3.1 将3.3.2中生成的客户端使用类和配置文件,添加到当前项目中
客户端项目的目录结构如下:
3.3.3.2 在Program.cs文件中编码如下,调用服务的方法
class Program { static void Main(string[] args) { CalculatorServiceClient calculator = new CalculatorServiceClient(); Console.WriteLine("{0}+{1}={2}",1.2,2,3,calculator.Add(1.2, 2.3)); Console.WriteLine("{0}-{1}={2}",3.4,2.3,calculator.Subtract(3.4, 2.3)); Console.WriteLine("{0}*{1}={2}",4.5,3.4,calculator.Mutiply(4.5, 3.4)); Console.WriteLine("{0}/{1}={2}",5.6,4.0,calculator.Devide(5.6, 4.0)); Console.WriteLine("Operation Over"); Console.WriteLine("Press any key to terminate the Console"); Console.Read(); } }
3.3.4 运行调试
3.3.4.1 先启动服务端程序ZWCFService
结果如下:
3.3.4.2 再启动客户端程序
如果客户端和服务端程序在同一个解决方案中,可将服务端设置为启动项,待服务端启动后,可以点击客户端右键—>调试-->启动新示例
用这样的方法来启动客户端,结果如下: