WCF入门教程系列三
一、WCF服务应用程序与WCF服务库
我们在平时开发的过程中常用的项目类型有“WCF 服务应用程序”和“WCF服务库”。
WCF服务应用程序,是一个可以执行的程序,它有独立的进程,WCF服务类契约的定义,可以直接看到运行的效果。此项目模板基于IIS托管的程序,如本系列的第一节所示。在开发基于IIS托管的WCF服务程序时,比较多见,自学的时候也可以使用这种类型,简单易懂。
WCF服务库,可以认为是一个包含WCF服务以及契约定义的类库。不能直接运行,你可以在其他项目里引用,在宿主里启用托管这个库,有点类似于我们在Web项目中应用的类库。考虑WCF服务设计的时候,服务类的定义为单独的库,可以为其它项目使用。提高代码的复用性。
当然你也可以修改这些代码,比如把WCF服务程序里的类,移到一个单独的类库里,或是把类库里的类移到WCF服务程序中。
二、概述
通过前面的介绍我们知道,WCF在运行时必寄宿在“宿主程序”之上,WCF本身不能够独自运行(每个WCF服务必须宿主在一个Windows进程中)。.net 提供了多种宿主供WCF运行,WCF还是非常灵活的。
WCF的宿主可以是 Windows 服务、COM+应用程序、WAS(Windows Activation Services,Windows进程激活服务)或IIS、Windows应用程序,或简单的控制台应用程序及任何.net程序。
这节的示例我们重新建立WCF类库项目为例做示例,名称为:WCFLibrary,并删除自动生成的两个文件(IService1.cs、Service1.cs)。如下图所示:
鼠标右键查看项目属性。我们发现,其实“WCF类库项目”与我们平时建立的 “类库项目”都是类库,只不过多了WCF的类库项目在新建时多了两个dll的引用(System.ServiceModel.dll、 System.Runtime.Serialization.dll)和一个自动生成的配置文件(该配置文件只用于调试时使用,在WCF寄宿以后会应用宿 主的配置文件与其他应用程序通信)。这更说明了我们在做分式程序开发的时候与我们平时开发的应用程序没有多大的区别,只要我们在应用程序间通信时“符合 WCF的约定”即可。
服务端我们还和第一个教程一样(IUser接口与User实现),只建立一个方法做为我们调用的示例代码如下:
1 //添加引用 2 using System.ServiceModel; 3 4 namespace WCFLibrary 5 { 6 [ServiceContract] 7 interface IUser 8 { 9 [OperationContract] 10 string ShowName(string name); 11 } 12 } 13 14 namespace WCFLibrary 15 { 16 class User : IUser 17 { 18 public string ShowName(string name) 19 { 20 string wcfName = string.Format("WCF服务,显示姓名:{0}", name); 21 return wcfName; 22 } 23 } 24 }
由于原来的契约为IService,现在的为IUser,所以配置文件有两处要修改为:
<service name="WCFLibrary.User">
<endpoint address="" binding="wsHttpBinding" contract="WCFLibrary.IUser">
点击“F5“运行效果如下图所示说明成功:
二、IIS宿主
我们在第一节中,把WCF寄宿在IIS之上,在IIS中宿主一个服务的主要优点是在发生客户端请求时宿主进程会被自动启动,并且你可以依靠IIS来管理宿主进程的生命周期。在开发和使用的过程与Web Service非常相似。
具体请参见本系列的第一节课程。
三、控制台应用程序宿主
建立宿主
(1)在解决方案下新建控制台输出项目 WCFHost_Console。
(2)添加 System.ServiceModel.dll 的引用。
(3)添加 WCF 服务类库(WCFLibrary)的项目引用。
(4)创建宿主程序,代码如下:
1 using System; 2 using WCFLibrary; 3 using System.ServiceModel; 4 using System.ServiceModel.Description; 5 6 namespace WCFHost_Console 7 { 8 class Program 9 { 10 static void Main(string[] args) 11 { 12 //创建宿主的基地址 13 Uri baseAddress = new Uri("http://localhost:8080/User"); 14 //创建宿主 15 using (ServiceHost host = new ServiceHost(typeof(User), baseAddress)) 16 { 17 //向宿主中添加终结点 18 host.AddServiceEndpoint(typeof(IUser), new WSHttpBinding(), ""); 19 //将HttpGetEnabled属性设置为true 20 ServiceMetadataBehavior smb = new ServiceMetadataBehavior(); 21 smb.HttpGetEnabled = true; 22 //将行为添加到Behaviors中 23 host.Description.Behaviors.Add(smb); 24 //打开宿主 25 host.Open(); 26 Console.WriteLine("WCF中的HTTP监听已启动...."); 27 Console.ReadLine(); 28 host.Close(); 29 } 30 } 31 } 32 }
(5)运行宿主程序[在客户端调用时要先运行宿主程序],如下图所示:
说明宿主建立成功。在上例中用到"ServiceHost"类,这里只是简单的应用,具体请查看"MSDN ServiceHost"。
建立客户端
(1)重新建立解决方案-->Web应用程序项目。
(2)添加对服务的引用(在引用上右键-->输入我们定义的服务宿主的基地址(此处为:http://localhost:8080/User)-->前往-->确定),具体请看第一节。
(3)测试程序如下图所示说明成功(注意:一定要先运行我们的宿主程序才行,如果宿主没有打开的话会报错:由于目标计算机积极拒绝,无法连接。)。
在这个示例中我们把Endpoint中的ABC,基地址,Behaviors等都直接写在了代码里,但实际应用过程中都是去依赖配置文件,为了对比说明我们下面的例子中会使用配置文件。
四、Windows应用程序宿主
建立宿主
(1)在解决方案下新建Windows窗体应用程序项目 WCFHost_Form。
(2)添加 System.ServiceModel.dll 的引用。
(3)添加 WCF 服务类库(WCFLibrary)的项目引用。
(4)添加应用程序配置文件App.config。
(5)创建宿主程序MainForm窗体,并修改App.config,代码如下:
1 <?xml version="1.0" encoding="utf-8" ?> 2 <configuration> 3 <system.serviceModel> 4 <services> 5 <service name="WCFLibrary.User"> 6 <host> 7 <baseAddresses> 8 <add baseAddress="http://localhost:8081/User"/> 9 </baseAddresses> 10 </host> 11 <endpoint address="" binding="wsHttpBinding" contract="WCFLibrary.IUser"></endpoint> 12 </service> 13 </services> 14 <behaviors> 15 <serviceBehaviors> 16 <behavior> 17 <serviceMetadata httpGetEnabled="True"/> 18 <serviceDebug includeExceptionDetailInFaults="False"/> 19 </behavior> 20 </serviceBehaviors> 21 </behaviors> 22 </system.serviceModel> 23 </configuration> 24 25 26 using System; 27 using WCFLibrary; 28 using System.ServiceModel; 29 using System.Windows.Forms; 30 using System.Configuration; 31 32 namespace WCFHost_Form 33 { 34 public partial class MainForm : Form 35 { 36 ServiceHost host; 37 38 public MainForm() 39 { 40 InitializeComponent(); 41 } 42 43 //应用程序加载 44 private void MainForm_Load(object sender, EventArgs e) 45 { 46 host = new ServiceHost(typeof(User)); 47 //打开宿主 48 host.Open(); 49 this.lblState.Text = "WCF中的HTTP监听已启动...."; 50 } 51 52 //应用程序关闭 53 private void MainForm_FormClosed(object sender, FormClosedEventArgs e) 54 { 55 host.Close(); 56 } 57 } 58 }
运行程序如下图所示:
建立客户端
同上边的Console程序一样,这里要引用的地址为:<add baseAddress="http://localhost:8081/User"/>
在这个例子中与Console应用程序不同的是,我们在Console配置是直接写在程序中的,而在本例中我们应用的是配置文件,区别在于如果写在配置文件中程序运行时直接到配置文件里取出相关的配置节去创建ServiceHost类。
五、WAS宿主
IIS7允许通过HTTP外的协议进行激活和网络通信。此环境适合开发可通过 WCF支持的任何网络协议(包括http、net.tcp、net.pipe、net.msmq)进行通信的WCF服务。部署简单、管理方便,这些网络协 议在部署时可像Http一样,直接丢到IIS7上即可,我们在下面的例子中以net.tcp为协议为例。IIS7以下的版本只能支持Http的通信。
1、确保已安装IIS7的激活组件
在应用WAS宿主时,必须确保IIS7的激活组件安装好。打开“控制面板”-->“打开或关闭Windows功能”-->“功能”,我的机器上已经安装过,如下图所示(WCF激活与非WCF激活):
如果没有安装,点击“添加新功能”,然后勾选“WCF激活”,如下图所示:
安装成功后我们打开IIS,点击“默认网站(任一个网站即可)”-->“绑定”-->“添加”,在类型中会出现非IIS支持的其他类型。如下图所示
说明安装成功。
2、添加net.tcp的网站绑定
在上图中,我们选择类型net.tcp,然后在绑定信息中填写“808:*”,点击确定。
3、开通net.tcp的协议
在安装成功并且在指定的网站上绑定了net.tcp以后,我们还要开通.net.tcp协议,点击我们要部署WCF的网站,在IIS管理器的操作功能区有一项“高级设置”点击后出现如下图所示高级配置的窗体
在启用的协议中添加net.tcp协议(原来只对http协议支持,现在把tcp协议追加上去),中间用逗号隔离开,如上图所示。
注意:这几个步骤一个也不能少,否则会出现:“找不到具有绑定 NetTcpBinding 的终结点的与方案 net.tcp 匹配的基址。注册的基址方案是 [http]”的错误信息。
4、建立服务程序
(1)在解决方案下新建WCF服务应用程序项目 WCFHost_WAS。
(2)建立IUser与User,代码同例二一样。
(3)修改配置文件代码如下:
1 <?xml version="1.0" encoding="utf-8"?> 2 <configuration> 3 <system.serviceModel> 4 <bindings> 5 <netTcpBinding> 6 <binding name="netTcpBindConfig"> 7 <security mode="None"> 8 <transport clientCredentialType="Windows" protectionLevel="EncryptAndSign" /> 9 <message clientCredentialType="Windows" /> 10 </security> 11 </binding> 12 </netTcpBinding> 13 </bindings> 14 <services> 15 <service behaviorConfiguration="MyBehavior" name="WCFHost_WAS.User"> 16 <endpoint address="" binding="netTcpBinding" contract="WCFHost_WAS.IUser" bindingConfiguration="netTcpBindConfig"></endpoint> 17 <!--元数据交换的终结点--> 18 <endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange" ></endpoint> 19 </service> 20 </services> 21 <behaviors> 22 <serviceBehaviors> 23 <behavior name="MyBehavior" > 24 <serviceMetadata/> 25 <serviceDebug includeExceptionDetailInFaults="true" /> 26 <dataContractSerializer maxItemsInObjectGraph="6553600"/> 27 </behavior> 28 </serviceBehaviors> 29 </behaviors> 30 </system.serviceModel> 31 32 </configuration>
(5)部署服务
像其他的Web应用程序一样,把相关的文件丢到服务器端指定目录即可。
鼠标右键浏览User.svc,如现如下所示:
说明部署成功,如上所示的服务地址为:net.tcp://服务器名/User.svc/mex
(6)建立客户端
建立客户端也与其他的一样,如下图所示:
我们此时看客户端的配置文件:
<client> <endpoint address="http://localhost:8080/User" binding="wsHttpBinding" contract="WCFHost_Console.IUser" /> <endpoint address="http://localhost:8081/User" binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IUser" contract="WCFHost_Form.IUser" name="WSHttpBinding_IUser"> <identity> <userPrincipalName value="WIN-EOUTAA4CP4O\Administrator" /> </identity> </endpoint> <endpoint address="net.tcp://win-eoutaa4cp4o/User.svc" binding="netTcpBinding" bindingConfiguration="NetTcpBinding_IUser" contract="WCFHost_WAS.IUser" name="NetTcpBinding_IUser" /> </client>
我们在一个Web应用程序中调用了三种不同宿主的服务。
七、总结
通过上面的几个例子,我们实现了控制台宿主、Form宿主、WAS宿主(基于TCP协议)的实现。在实际的开发过程中,有时候我们还会用到基于Windows服务的宿主,但大部份都使用IIS做宿主,方便、快捷。
八、代码下载
九、版权
转载请注明出处:http://www.cnblogs.com/iamlilinfeng
WCF入门教程系列三的更多相关文章
- WCF入门教程(三)定义服务协定--属性标签
WCF入门教程(三)定义服务协定--属性标签 属性标签,成为定义协议的主要方式.先将最简单的标签进行简单介绍,以了解他们的功能以及使用规则. 服务协定标识,标识哪些接口是服务协定,哪些操作时服务协定的 ...
- WPF入门教程系列三——Application介绍(续)
接上文WPF入门教程系列二——Application介绍,我们继续来学习Application 三.WPF应用程序的关闭 WPF应用程序的关闭只有在应用程序的 Shutdown 方法被调用时,应用程序 ...
- WCF入门教程系列一
一.概述 Windows Communication Foundation(WCF)是由微软发展的一组数据通信的应用程序开发接口,可以翻译为Windows通讯接口,它是.NET框架的一部分.由 .NE ...
- WCF入门教程系列五
一.概述 WCF在通信过程中有三种模式:请求与答复.单向.双工通信.以下我们一一介绍. 二.请求与答复模式 描述: 客户端发送请求,然后一直等待服务端的响应(异步调用除外),期间处于假死状态,直到服务 ...
- WCF入门教程系列二
一.概述 WCF能够建立一个跨平台的安全.可信赖.事务性的解决方案,是一个WebService,.Net Remoting,Enterprise Service,WSE,MSMQ的并集,有一副很经典的 ...
- WCF入门教程系列六
一.前言 前面的几个章节介绍了很多理论基础,如:什么是WCF.WCF中的A.B.C.WCF的传输模式.本文从零开始和大家一起写一个小的WCF应用程序Demo. 大多框架的学习都是从增.删.改.查开始来 ...
- WCF入门教程系列四
一.概述 配置也是WCF编程中的主要组成部分.在 以往的.net应用程序中,我们会把DBConn和一些动态加载类及变量写在配置文件里.但WCF有所不同.他指定向客户端公开的服务,包括服务的地址. 服务 ...
- WCF入门教程(三)属性标签
属性标签,成为定义协议的主要方式.先将最简单的标签进行简单介绍,以了解他们的功能以及使用规则. 服务协定标识,标识哪些接口是服务协定,哪些操作时服务协定的一部分,以及传输对象的定义.如果已经有所了解, ...
- WPF入门教程系列三
WPF之Binding的使用(一) 一. 前言 初学WPF经常被Binding搞得苦不堪言,Binding的重用性就不做介绍了,在WPF应用程序开发中Binding是一个非常重要的部分.WPF也是近 ...
随机推荐
- 14 java 日期处理 joda-time
http://www.joda.org/joda-time/ 任何企业应用程序都需要处理时间问题.应用程序需要知道当前的时间点和下一个时间点,有时它们还必须计算这两个时间点之间的路径.使用 JDK 完 ...
- C#数组的指定位置复制函数
1. // 源数组 - 起始位置 -目的数组 - 起始位置 - 长度 System.Array.Copy(mcu_data, 2, read_mcu_data_whole, 0, mcu_data.L ...
- c#串口编程时,忽略跨线程检查报错
1.直接在main_Form_Load的初始化中加 //忽略跨线程检查 // System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls ...
- C++中explicit
[explicit] 1.用于抑制隐式转换,即: X x = ; // error X x(); // ok 2.只对一个实参的构造函数有效,但是,可以用多有多个实参的构造函数,目前没有意义: cla ...
- UWP开发小记
针对个人的上一篇文章中提到的遇到的几个问题,做一下个人解答 DLL部署的问题,可以将DLL添加到工程中,属性中设置content为true,这样,部署目录下就会有这个文件. 需要说明的是,这个文件确实 ...
- jquery简单的拖动效果
<!DOCTYPE html> <html> <meta http-equiv="Content-Type" content="text/h ...
- inline-block样式间距
原始问题和解决方法请参考 淘宝UED官方博客:inline-block 前世今生 布局时采用行内块display:inline-block,发现元素之间有空隙,原因是由于空白字符引起的,详细见上面链接 ...
- 使用nRF51822/nRF51422创建一个简单的BLE应用 ---入门实例手册(中文)之五
5应用测试 需要一个USB dongle与开发板evaluation kit,并配合Master Control Panel软件,以用于测试BLE应用.前期的准备工作在<nRF51822 Eva ...
- Effective Java2读书笔记-对于所有对象都通用的方法(一)
第8条:覆盖equals时请遵守通用约定 ①约定的内容 自反性.对于任何非null的引用值x.x.equals(x)必须返回true. 对称性.对于任何非null的引用值x和y.当且仅当y.equal ...
- JS 浮点计算BUG
最近做项目的时候遇到一个比较纠结的js浮点计算问题. 当时是做利率计算,因为利率大多数涉及到小数点,精度要求也很高. 0.6+0.1+0.1=? 结果出现:0.7999999999999 网上查找了一 ...