WCF( Windows Communication Foundation )基础

WCF(一) Windows Communication Foundation 概述

WCF被推出来很久了,但是对于刚刚接触WCF的人们来说,想必会有以下问题:

WCF是什么?为什么我们需要WCF?WCF能给我们带来什么?学习WCF的难易度如何?

以上这些问题的答案在网上已经很多介绍了,我在此本不必再浪费口舌,只是大概提一下。

WCF: Windows Communication Foundation.从名字可以看出,这是一项和通信密切相关的技术。我们知道软件设计到处是通信。当然我们必须学了以后,才能更好的知道它、运用它,而不能单单从它的名字揣测它的威力如何。

WCF提供给了我们一种面向服务(SOA)的程序设计的解决方案:何为面向服务?之前有使用过.NET Web Service 开发的朋友,很容易理解面向服务是咋回事。.Net Web Service也是更早的时候微软提出的一种面向服务的解决方案。面向服务是一种标准,不同的公司可以给出各自的实现框架。单纯的讲SOA,毕竟太抽象了。学习一下SOA的一种实现比如.Net Web Service 或WCF以后,相信不用任何文字定义,你也会深刻地理解SOA。所以,何为面向服务?这里不解释,等你学一段时间的WCF,你自己就有答案了,真的,呵呵。

WCF提供了统一的通信模型:以前我们写通信可以是:TCP/UDP,Socket等这些方式,在WCF中被统一了。至于如何统一?这里先不说了。所以,当你在项目中同时使用了多种通信方式时,可以考虑使用WCF了。

以前没有接触过Web Service 开发接受WCF也不是难事,相信我!

这次,我们只做一点WCF的概述,更为详细的知识到后面再慢慢展开。边学习,边交流。

1. 打开VS 2010 -->file-->new Project ,选择C#下面的WCF,选择WCF Library。如下图:

2.此时有了IService 文件和一个Service 文件。Service文件实现的IService中的两个函数:GetData函数和GetDataUsingDataContract函数。至于这两个函数是干嘛的?想必不用说大家都能看懂的。之后详细说明他们的角色。这里也不修改类名和函数名了,方面起见。

3.按F5运行程序,此时打开了一个WCF 的一个测试 窗口。如下图:先测试GetData函数

测试结果:

同样的方法测试GetDataUsingDataContract函数:结果如下图

4.上面完成了对WCF的函数功能的简单测试,能说明的是Service正确地实现了IService。接下来我们需要将这个WCF部署到一个Web Site中。

在解决方案上面右击:New -->New Web Site 如下图:

修改web site项目中的Service.svc 文件里面的 Service="WcfFirstDemoServiceLib.Service1" (其中意思就是已命名空间加类名的方式指定service的名字)

 

 5.添加一个winForm程序 ,用它来调用WCF的函数。

6.给winForm 项目添加web 引用:

7.在Form1上面添加几个控件,然后再在Form1.cs中添加下列几行代码:

Form1.cs

8.Ctrl+F5 运行:

 

说明:这里只是概述WCF,所以全部在使用WCF的默认设置,也没有详细说明每一步的作用是什么。只是给出三个项目:项目1是WCF的库也是WCF功能核心。项目2是WCF的host用于向外界发布WCF提供的接口(:接口这里指提供了哪些函数可被调用)。项目3是WCF的客户端用于调用WCF。其实,这里已经隐约体现出一点点分布式软件架构的意思了:有专门提供功能实现的模块,有专门提供对外公开接口的模块,有专门作为调用的模块。

后面详细WCF每一部分的。欢迎关注!!

WCF(二) Contract

上篇只是介绍了WCF的概述。具体的设置全是使用默认,这当然不可能满足我们开发的需要。如果仔细理一理的话,你会发现WCF里面的设置其实不算多的(与SharePoint比较的话)。从这篇开始,我们一点一点来展开学习。这次先提最最常用的Contract。

Contract有人翻译为:协定,契约。

WCF中有四种contract: 分别是:1.Service Contract. 2.Data Contract. 3. Fault Contract. 4.Message Contract.

还拿上篇中的例子(其实就是有Visual Studio2010替我们默认生成的代码了)说事:

1.Service Contract共分为两个部分:定义部分和实现部分。

复制代码
 1     [ServiceContract]
 2     public interface IService1
 3     {
 4         [OperationContract]
 5         string GetData(int value);
 6 
 7         [OperationContract]
 8         CompositeType GetDataUsingDataContract(CompositeType composite);
 9       
10     }
复制代码

这里IService就是一个service contract的定义部分,指定了哪些函数(Operation)向外公开(即:可供Client调用)。被[OperationContract]修饰的函数可以被客户端(Client)调用。
[OperationContent]是Attribute。关于Attribute不太明白的,请参考:《别弄混了C#.的几个小概念Attribute,property,field

复制代码
 1     public class Service1 : IService1
 2     {
 3         public string GetData(int value)
 4         {
 5             return string.Format("You entered: {0}", value);
 6         }
 7 
 8         public CompositeType GetDataUsingDataContract(CompositeType composite)
 9         {
10             if (composite == null)
11             {
12                 throw new ArgumentNullException("composite");
13             }
14             if (composite.BoolValue)
15             {
16                 composite.StringValue += "Suffix";
17             }
18             return composite;
19         }
20     }
复制代码

Service1实现了IService接口,是Service Contract 的实现部分。VS自动生成的代码太简单了,不解释了。这里为了尽可能简单地说明问题。具体项目中,你可能需要连接数据库增、删、改、查数据,或对数据按n多复杂的业务规则进行数据处理以后,返回给client,等。
[ServiceContract] Attribute 可以有以下Property 的:

CallbackContract设置callback的类型:Duplicate指Service Host和Client之间进行双向通信
ConfigurationName指定配置文件中某个configuration的名字
HasProtectionLevel标示是否可以处理安全消息
Name给contract指定一个名字,在client端可见的名字,默认就是接口名字
Namespace给消息指定一个命名空间
ProtectionLevel 
SessionMode指允许,还是不允许,还是强制session

 

 

 

 

 

 

[OperationContract] Attribute 可以有以下Property 的:

Action对请求设置WS-Addressing 的action
AsynchPattern异步模式
HasProtectionLevel消息是否加密,签名
IsInitiating表明该函数被调用开始时是否要在server上面初始化一个session
IsOneWay表明函数被client调用以后,client是否会等待函数返回
IsTerminating表明该函数被调用结束时是否要在server上面关闭session
Name设置函数的名字,在client端可见的名字,默认就是函数名字
ProtectionLevel 
ReplyAction设置函数返回消息的SOAP action

 

 

 

 

 

 

 

 

1.1 我们修改一下Service的默认命名空间,使他更make scene(有意义).

打开上篇中的解决方案WcfFirstDemo.sln

右键WebHost项目下面的文件:Service.svc,如下图:

点击连接如图:

得到如图效果:

默认Namespace是http://tempuri.org/

微软官方建议:修改Service的Namespace,使其包含:公司域名+项目名+版本号(如:日期表示版本号)

修改项目:WcfFirstDemoServiceLib下面的IService.cs代码如下:

复制代码
 1     [ServiceContract(Namespace="http://wwww.cnblogs.com/WCF/2012/07/28")]
 2     public interface IService1
 3     {
 4         [OperationContract]
 5         string GetData(int value);
 6 
 7         [OperationContract]
 8         CompositeType GetDataUsingDataContract(CompositeType composite);
 9       
10     }
复制代码

右键项目WcfFirstDemoServiceLib 选择重新编译,成功以后,重新用浏览器打开service.svc,得到如下图:

此时已经改变了Service默认的Namespace了,client端需要更新一下,否则运行client端是会报异常的.操作如下图:

1.2修改Service的Name.默认情况下定义service的接口部分(如本例:IService)的名字就是Service的名字.但有时需要让client看到的service的名字跟server端看到的的service名字不一样.

我们先看一下WCFClient项目下面的app.config

修改WcfFirstDemoServiceLib项目下的IService.cs文件

复制代码
 1     [ServiceContract(Namespace="http://wwww.cnblogs.com/WCF/2012/07/28",Name="DemoService")]
 2     public interface IService1
 3     {
 4         [OperationContract(Name="GetAge")]
 5         string GetData(int value);
 6 
 7         [OperationContract]
 8         CompositeType GetDataUsingDataContract(CompositeType composite);
 9       
10     }
复制代码

重新编译WcfFirstDemoServiceLib项目.更新client端对service的引用.此时你会发现client端app.config文件前后发生了变化:

此时WCFClient所生成的代理类的名字也会变化,你需要修改WCFClient

1    DemoService proxy = null;
1         private void Form1_Load(object sender, EventArgs e)
2         {
3             proxy = new DemoServiceClient("BasicHttpBinding_DemoService");
4 
5         }
1         private void btnGetData_Click(object sender, EventArgs e)
2         {
3             this.tbOutputBox.Text = proxy.GetAge(Convert.ToInt32(this.tbInputbox.Text));
4         }

:上面代码中DemoService 对应server端IService接口;DemoServiceClient对应server端的Service类.

当client端的app.config文件中只包含一个endpoint时,可以直接用proxy=new DemoServiceClient()传空参数,当然也可以传这个endpoint的name进去;但是当app.config包含多个endpoint时必须把endpoint的name传进去才能new出proxy对象.

2.DataContract.

WCF的Server和client之间利用特定格式的Message(消息)进行通信的。但是我们使用的高级语言:不论在Server端还是在client端,我们处理的业务数据都被封装成了对象。所以想把server端的对象传送到client(或相反方向)时,我们必须有能力把这些对象转换成特定格式的message,到另一端接收到message后再把它转回成对象。C#的基础类型(如int,string,float,bool等)可以做到这一点。因为一旦确定了Server端或client所用的编程语言,就可以确定这些基础类型的内存占用情况(例如:一个Server端定义的int变量在C#中占用多大内存空间是已知的,那么client端即便使用的是其他语言也完全可以计算出该变量的内存占用情况)。可是我们自己定义的类型可是五花八门了(比如:server端定义的Person类new出的object到底占用多大内存空间,就算Server端与client端使用同一种语言,Client端是不知道的Person类的对象的内存占用情况的。)

遇到这种请款下,我们怎么办呢?这时就轮到[DataContract]露面了。

遇到这种请款下,我们怎么办呢?这时就轮到[DataContract]露面了。

ServiceContract做的工作是指定service向client提供了哪些函数可供调用。DataContract做的工作就是指定在Server端与client端之间可以传送的数据。[DataContract]的作用就是指定当需要传送某个类(如:Person类)的对象时,将该对象转化成为XML.接受方接到XML以后,再按同样的方式还原成对象。

[DataContract]Attribute 标在class定义上面一行。[DataMember]Attribute标在Property定义上面一行,field不需要Attribute修饰。

复制代码
 1     [DataContract]
 2     public class CompositeType
 3     {
 4         bool boolValue = true;
 5         string stringValue = "Hello ";
 6 
 7         [DataMember]
 8         public bool BoolValue
 9         {
10             get { return boolValue; }
11             set { boolValue = value; }
12         }
13 
14         [DataMember]
15         public string StringValue
16         {
17             get { return stringValue; }
18             set { stringValue = value; }
19         }
20     }
复制代码

[DataContract]Attribute 可以像[ServiceContract]一样设置Name和Namespace.
[DataMember] Attribute 可以有以下属性:

EmitDefaultValue设置一个默认值
IsRequired进行序列化/反序列化时该值一定不可为空值
NameProperty的名字
Order设置进行序列化/反序列化的顺序

 

 

 

 

 2.1修改DataContract的默认namespace , 

复制代码
 1    [DataContract(Namespace = "http://wwww.cnblogs.com/WCF/2012/07/28", Name = "CompositeTypeDemo")]
 2     public class CompositeType
 3     {
 4         bool boolValue = true;
 5         string stringValue = "Hello ";
 6 
 7         [DataMember(Name="GetBool")]
 8         public bool BoolValue
 9         {
10             get { return boolValue; }
11             set { boolValue = value; }
12         }
13 
14         [DataMember(Name="GetString")]
15         public string StringValue
16         {
17             get { return stringValue; }
18             set { stringValue = value; }
19         }
20     }
复制代码

这样在client端看到的类(class)名,函数名与server看到的就不相同.

 3.Fault Contract.

在WCF中处理异常(Exception)的方法有些特殊.我们不能单从server处理exception,需要进一步将Exception从server传送到client. 在后面我们再单独讨论WCF的Exception处理.

4. Message Contract.

Message Contract与Data Contract都是作用在传送的对象(object)上面.

不同的是:

datacontract是将object序列化化为xml. 实现object的各个property与xml 文本中各个node(节点)的对应);

messagecontract将对象组装成message(指定Message的Header,body).实现的是object各个property与消息的各个元素的对应.

具体的深层区别于联系,以及使用场景,我还不懂,希望有朋友对着块比较懂的,可以交流一下.如果后面等我弄懂了的话,我再专门写博文交流.

WCF(三) Message pattern

上次咱们稍稍讨论了WCF中的contract,这次咱们讨论Message Pattern.

WCF中为何会有message pattern呢?

我们知道WCF的Server端与client端是通过xml 来进行交互的.message pattern其实就是指server端与client端交互xml的方式.

wcf提供以下三种pattern:

1.Request-reply:client端调用server端的公开的method后,client端需等server端method返回结果(即:reply响应)以后,才能做继续client端的下一步操作.(如:client调用server端的method往数据库中插入一条数据.server端插入数据成功以后,返回相应的数据库插入成功信息.很多情况下使用的是这种.

2.one-way:client端调用server端的公开的method后,client端不需等server端的method返回结果,便可继续client端下一步操作.(如:server端记录client端的日志(log)信息).标识为One-way的operation(函数)的返回值只能是void. 当client向server 发起了request后,不需要server做出回应的情况使用one-way message pattern.

3.duplicate:Request-Reply 和One-way都是先由client端发起的request(请求);duplicate则允许有server端发起request.

两种方式实现duplicate:一种是tcp(这里先不讲tcp的方式,先讲http的方式).一种是http. Http方式的话:是先由client端发起一次one-way 的request,然后client不等待server端返回结果,而是端继续往下执行.当server端有结果返回时,再有server端发起一次one-way的request.所以duplicate也叫callback. 我们知道当一个操作很费时的话,为了减少UI的无响应,有更好的用户体验,会使用callback.wcf也是:当server的执行很耗时的话,我们可以使用duplicate的message pattern.

4.实现:

4.1:Requst-Reply:是最简单的

复制代码
 1     [ServiceContract(CallbackContract = typeof(IDuplicateDemoCallback))]
 2     public interface IService1
 3     {
 4         // 在函数中,我们让线程暂停,模拟耗时的操作.
 5         // 参数:interval为暂停的毫秒数,由调用该method的client端设定.
 6         [OperationContract]
 7         void RequestReply(int interval);
 8 
 9         [OperationContract]
10         void DuplicateCommunicate(int interval);
11 
12     }
复制代码

4.2:One-Way:(只需要在requst-reply的基础上,使operationContract 的IsOneWay=true即可)

复制代码
 1     [ServiceContract(CallbackContract = typeof(IDuplicateDemoCallback))]
 2     public interface IService1
 3     {
 4         // 在函数中,我们让线程暂停,模拟耗时的操作.
 5         // 参数:interval为暂停的毫秒数,由调用该method的client端设定.
 6         [OperationContract(IsOneWay = true)]
 7         void RequestReply(int interval);
 8 
 9         [OperationContract(IsOneWay = true)]
10         void DuplicateCommunicate(int interval);
11 
12     }
复制代码

4.3Duplicate:(有些复杂)有以下步骤:
4.3.1:在server端IService.cs文件中添加代码:

复制代码
 1     // NOTE: You can use the "Rename" command on the "Refactor" menu to change the interface name "IService1" in both code and config file together.
 2     [ServiceContract(CallbackContract = typeof(IDuplicateDemoCallback))]
 3     public interface IService1
 4     {
 5         // 在函数中,我们让线程暂停,模拟耗时的操作.
 6         // 参数:interval为暂停的毫秒数,由调用该method的client端设定.
 7         [OperationContract(IsOneWay=true)]
 8         void RequestReply(int interval);
 9        
10         [OperationContract(IsOneWay=true)]
11         void DuplicateCommunicate(int interval);
12 
13 
14     }
15 
16     public interface IDuplicateDemoCallback
17     {
18         [OperationContract(IsOneWay=true)]
19         void DuplicateCommunicateCallback(string callbackMessage);
20     }
复制代码

4.3.2:在web site项目下的web.config文件:使其支持wsDua

复制代码
 1 <?xml version="1.0"?>
 2 <configuration>
 3 
 4   <system.web>
 5     <compilation debug="false" targetFramework="4.0" />
 6   </system.web>
 7   <system.serviceModel>
 8     <behaviors>
 9       <serviceBehaviors>
10         <behavior>
11           <!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
12           <serviceMetadata httpGetEnabled="true"/>
13           <!-- To receive exception details in faults for debugging purposes, set the value below to true.  Set to false before deployment to avoid disclosing exception information -->
14           <serviceDebug includeExceptionDetailInFaults="false"/>
15         </behavior>
16       </serviceBehaviors>
17     </behaviors>
18     <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
19 
20     <services>
21       <service name="WcfMessagePatternLib.Service1" behaviorConfiguration="">
22         <!-- Service Endpoints -->
23         <endpoint address="" binding="wsDualHttpBinding" contract="WcfMessagePatternLib.IService1">     
24           <identity>
25             <dns value="localhost"/>
26           </identity>
27         </endpoint>
28         <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
29       </service>
30     </services>
31     
32     
33     </system.serviceModel>
34   <system.webServer>
35     <modules runAllManagedModulesForAllRequests="true"/>
36   </system.webServer>
37   
38 </configuration>
复制代码

4.3.3在client端添加一个类文件命名为Callback.cs:
使其实现IDuplicateDemoCallback接口.

复制代码
1     class Callback:ServiceReference1.IService1Callback
2     {
3         public void DuplicateCommunicateCallback(string callbackMessage)
4         {
5             MessageBox.Show(callbackMessage);
6         }
7     }
复制代码
1         private void Form1_Load(object sender, EventArgs e)
2         {
3             var context = new InstanceContext(new Callback());
4             proxy = new Service1Client(context);
5         }

 4.3.4修改client项目下的app.config文件:使其支持wsdualhttp

复制代码
 1 <?xml version="1.0" encoding="utf-8" ?>
 2 <configuration>
 3     <system.serviceModel>
 4         <bindings>
 5             <wsDualHttpBinding>
 6                 <binding name="WSDualHttpBinding_IService1" closeTimeout="00:01:00"
 7                     openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
 8                     bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard"
 9                     maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
10                     messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true">
11                     <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
12                         maxBytesPerRead="4096" maxNameTableCharCount="16384" />
13                     <reliableSession ordered="true" inactivityTimeout="00:10:00" />
14                     <security mode="Message">
15                         <message clientCredentialType="Windows" negotiateServiceCredential="true"
16                             algorithmSuite="Default" />
17                     </security>
18                 </binding>
19             </wsDualHttpBinding>
20         </bindings>
21         <client>
22             <endpoint address="http://localhost:8167/WebHost/Service.svc"
23                 binding="wsDualHttpBinding" bindingConfiguration="WSDualHttpBinding_IService1"
24                 contract="ServiceReference1.IService1" name="WSDualHttpBinding_IService1">
25                 <identity>
26                     <dns value="localhost" />
27                 </identity>
28             </endpoint>
29         </client>
30     </system.serviceModel>
31 </configuration>
复制代码

 

WCF(四) Configuration file (配置文件)

前面大致介绍了点wcf的几个小小的基本概念. 任何一个新技术,都能给我们带来一大堆的基本概念. 当然WCF也不例外. 关于WCF更多的概念,在以后再讨论.我们先讨论如何在不深入了解这一大堆学术定义的前提下,使用这项技术.

在开发过程中,使用configuration file (配置文件)具有很灵活的好处:以后有关于配置的改变,不必重新编译代码,只需打开configuration file 改一下就行了,省时省力.

WCF中configuration file的地位不可忽视.当然我们可以使用code的方式,实现WCF的服务的每个阶段. 但我们的软件产品是需要给客户在实际工作中使用的. 我们要让软件产品的后期维护尽可能的简单,省时省力.

WCF的核心是Service. 一个service有包含多个endpoint, 如下图:

打开VS2010,File-->New project. 选择WCF Service Library 模板. Solution Name 和project Name我们都用默认的. 点击OK.

此时创建了一个WCF Library project. 打开App.config 文件,你会看到以下内容:

复制代码
 1 <?xml version="1.0" encoding="utf-8" ?>
 2 <configuration>
 3 
 4   <system.web>
 5     <compilation debug="true" />
 6   </system.web> 
 7   <system.serviceModel>
 8     <services>
 9       <service name="WcfServiceLibrary4.Service1">
10         <host>
11           <baseAddresses>
12             <add baseAddress = "http://localhost:8732/Design_Time_Addresses/WcfServiceLibrary4/Service1/" />
13           </baseAddresses>
14         </host> 
15         <endpoint address ="" binding="wsHttpBinding" contract="WcfServiceLibrary4.IService1">
16           <identity>
17             <dns value="localhost"/>
18           </identity>
19         </endpoint>    
20         <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
21       </service>
22     </services>
23     <behaviors>
24       <serviceBehaviors>
25         <behavior>
26           <serviceMetadata httpGetEnabled="True"/>       
27           <serviceDebug includeExceptionDetailInFaults="False" />
28         </behavior>
29       </serviceBehaviors>
30     </behaviors>
31   </system.serviceModel>
32 
33 </configuration>
复制代码

注:

第1行,定义该xml file的版本和使用的字符集. 是关于该配置文件的基本信息,与程序配置无关,只管保持默认即可.

第2行,<configuration> node,关于程序内的配置,都必须包含在此node里面.

第5行,是关于debug配置. 如果是在开发阶段,把它设为true,这样调试起来方便.

第7--31行,是<system.serviceModel> node, 关于wcf service的核心配置都在这个node里面. 该node下面有两个子node:一个是<services>,另一个是<behaviors>. 除此以外,还可以有<bindings>等.<services>是<service>的集合;<behaviors>是<behavior>的集合;<bindings>是<binding>的集合.

多说一句: WCF程序设计需要注意两方面的模型:一是编程模型;二是通信模型. 一般我们做web开发只需要编程模型,通信就交给http了. 但是wcf允许我们使用http以外的其他通信协议.所以,我们考虑了编程还必须考虑通信模型.好在wcf给我们提供了方便之处:它屏蔽了开发人员对通信模型的处理,只需要我们通过bindings API创建通信模型即可. 所以,我们对bindings的指定,就是在处理通信模型.

第8--22行,是<services>node,该node下面有多个<service>node.

第9--21行,是<service>node,它的name指定了实现这个service的类名(全名,包括namespace).该<services>下面有一个<host>node,和多个<endpoint>node.(如上面我们提到的那张图) .

第10行,是<host>node, <host>下面有<baseAddress>.

第11-13行,<baseAddress> node, <add>增加一个该service的基址,<endpoint>里面的address就相对于这个baseAddress的. 如果有多个baseAddress的话是根据<endpoint>所指定的binding方式与baseAddress的形式匹配的.(如,<endpoint>所指定的binding方式是netTcpBinding,就会匹配以net.tcp://打头的baseAddress.)

 第15行,<endpoint>node,<endpoint>除了name以外,还有最重要的三部分组成,简称:ABC. A是Address,B是Binding,C是Contract. Address可以是一个完整的URL,或是一个相对于基址的URL,如果为空,则使用基址.Binding指定通信模型比如:http,tcp,mssq等. Contract就是服务的contract(就是前面我们使用[OperationContract]修饰的那个服务接口).

第20行,是元数据的<endpoint>,用与发布一些元数据信息.

先到这吧.....

WCF(五) Host WCF Service

这次我们讨论Host a WCF service.

前述

为了让client可以使用service,我们必须host service到一个每时每刻都在运行的环境中(我们叫Host Application),因为它时刻等待着来自client的request(请求). Host有人翻译成"寄宿",我仍使用Host. Host application负责start和endservice, 然后监听来自client的request,解析client的request,然后调用相应的service. 最后把结果返回给client.

 

Host Application为每一个Service 创建一个ServiceHost对象. 当有多个Service是,就会创建多个ServiceHost对象. 当client需要使用多种protocol(通信协议),如Http和tcp,此时你不必创建多个service, 因为前面我们知道一个Service可以有多个endpoint(endpoint 包含Address,Binding,Contract). Binding指定不同的protocol,所以,我们只需创建多个endpoint,在binding中指定不同的protocol即可.

可以把service host到以下环境中:

1.IIS:我们需要创建一个Web Site,使用该Website去host wcf,然后将该website放到IIS中. 如果你使用了IIS去host wcf,那么只能使用http protocol. 当有request到来时,host application可以自动激活,并开始监听.

2.WAS:(Windows Process Activation Service)作为IIS7.0的一个新特性.我们同样需要创建一个web site .Vista,Windows 7, Windows Server2008 等操作系统可以安装WAS.  如果你使用了WAS去host wcf,可以使用http ,tcp,MSMQ,Named Pipe protocol. 当有request到来时,host application可以自动激活,并开始监听.

3.Managed Application(托管程序,如Console,WinFrom,WPF): Self-Hosting. 当有request到来时,host application不能自动激活.需要在代码中手动new出serviceHost对象.

我们如何选择哪一种host方式呢?

答案是:取决于你的操作系统,和通信需求,和特定场景.

1.如果你的操作系统是windows server2003,并且程序只用http即可满足需求. 那么使用IIS去host. 如果程序除了使用http不可满足需求(除了http,还需要tcp),则要创建window 服务去host.

2.如果你的操作系统是windows server2008(或 windows 7 )使用WAS. 因为它可以支持更多的protocol.

3.如果仅仅用于演示,可以使用Console去host. 但是release到真正的产品时,最好用winForm或WPF.

对于每一种方式,我们如何实现呢?





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值