无废话WCF入门教程三[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的宿主]的更多相关文章
- 无废话ExtJs 入门教程三[窗体:Window组件]
无废话ExtJs 入门教程三[窗体:Window组件] extjs技术交流,欢迎加群(201926085) 1.代码如下: 1 <!DOCTYPE html PUBLIC "-//W3 ...
- WCF入门教程三[WCF的宿主]
一.WCF服务应用程序与WCF服务库 我们在平时开发的过程中常用的项目类型有“WCF 服务应用程序”和“WCF服务库”. WCF服务应用程序,是一个可以执行的程序,它有独立的进程,WCF服务类契约的定 ...
- 【转】WCF入门教程三[WCF的宿主]
一.WCF服务应用程序与WCF服务库 我们在平时开发的过程中常用的项目类型有“WCF 服务应用程序”和“WCF服务库”. WCF服务应用程序,是一个可以执行的程序,它有独立的进程,WCF服务类契约的定 ...
- 无废话SharePoint入门教程三[创建网站集和网站]
一.前言 前两篇文章讲解了什么是SharePoint,并且介绍了在SharePoint中一些常用的概念.但概念终究是概念,我们还是要脚踏实地的去动手实践.下面的文章对于了解SharePoint的人来说 ...
- 无废话ExtJs 入门教程十六[页面布局:Layout]
无废话ExtJs 入门教程十六[页面布局:Layout] extjs技术交流,欢迎加群(201926085) 首先解释什么是布局: 来自百度词典的官方解释:◎ 布局 bùjú: [distributi ...
- 无废话ExtJs 入门教程十五[员工信息表Demo:AddUser]
无废话ExtJs 入门教程十五[员工信息表Demo:AddUser] extjs技术交流,欢迎加群(201926085) 前面我们共介绍过10种表单组件,这些组件是我们在开发过程中最经常用到的,所以一 ...
- 无废话ExtJs 入门教程二十一[继承:Extend]
无废话ExtJs 入门教程二十一[继承:Extend] extjs技术交流,欢迎加群(201926085) 在开发中,我们在使用视图组件时,经常要设置宽度,高度,标题等属性.而这些属性可以通过“继承” ...
- 无废话ExtJs 入门教程二十[数据交互:AJAX]
无废话ExtJs 入门教程二十[数据交互:AJAX] extjs技术交流,欢迎加群(521711109) 1.代码如下: 1 <!DOCTYPE html PUBLIC "-//W3C ...
- 无废话ExtJs 入门教程十九[API的使用]
无废话ExtJs 入门教程十九[API的使用] extjs技术交流,欢迎加群(201926085) 首先解释什么是 API 来自百度百科的官方解释:API(Application Programmin ...
随机推荐
- 流动python - 什么是魔术方法(magic method)
我们经常看到各种各样的方法已经被包围了由双下划线,例如__init__,他们是魔术方法. 魔术方法python语言预订好"协议",在不同情况下不同的魔术方法,是隐式调用.我们重写这 ...
- 信息二战炸弹:中国到美国咨询公司Say no
疯抢/文 在禁止Windows8操作系统參与政府採购,以及在中国销售的全部外国IT产品和服务都须通过新的安全审查之后,英国<金融时报>今天报料中国已禁止国企使用美国咨询公司服务. 这则消息 ...
- Android尽量避免使用开发jpg图片
因为jpgeasy失真,因此,Android尽量避免使用开发.jpg图片,相反,使用.png图片,它使用LZ77衍生无损数据压缩算法. 事实上在这一点上,Google他已经暗示我们: 发现了没有,在r ...
- EJB(一)认识ejb
什么是ejb? 相同仍旧在这个系列博客之处,谈谈对ejb的认识和理解. sun微公司对于ejb的定义大体是这种,ejb是一套用于开发和部署分布式组件的的架构.採用ejb的架构应用能够是 ...
- 错误21002:[SQL-DMO]用户"xxx"已经存在
原文:错误21002:[SQL-DMO]用户"xxx"已经存在 转载自:http://topic.csdn.net/u/20120829/09/faf381b6-d4e9-4f97 ...
- HDU2647(拓扑排序+反向建图)
题意不说了,说下思路. 给出的关系是a要求的工资要比b的工资多,因为尽可能的让老板少付钱,那么a的工资就是b的工资+1.能够确定关系为a>b,依据拓扑排序建边的原则是把"小于" ...
- flipsnap.js 源码阅读备份
这是官网:http://hokaccha.github.io/js-flipsnap/ 1.引入全局命名空间 类似jQuery插件写法 传入window, document,提高内部访问速度: ; ...
- PS 过滤器——运动模糊
%%%%% motion blur clc; clear all; close all; Image=imread('4.jpg'); Image=double(Image); theta=pi/4 ...
- UVA 1364 - Knights of the Round Table (获得双连接组件 + 二部图推理染色)
尤其是不要谈了些什么,我想A这个问题! FML啊.....! 题意来自 kuangbin: 亚瑟王要在圆桌上召开骑士会议.为了不引发骑士之间的冲突. 而且可以让会议的议题有令人惬意的结果,每次开会前都 ...
- NSIS:强制结束软件进程
原文NSIS:强制结束软件进程 有时候,我们选择卸载软件后发现安装目录中的主文件依然存在,不是我们卸载代码写的不对,而是卸载的时候软件根本就没有关闭! 在卸载前加上下面这个宏可以在一定程度上免除上述的 ...