当前位置:文档之家› 我的WCF之旅(1):创建一个简单的WCF程序

我的WCF之旅(1):创建一个简单的WCF程序

我的WCF之旅(1):创建一个简单的WCF程序
我的WCF之旅(1):创建一个简单的WCF程序

https://www.doczj.com/doc/1218648008.html,/artech/archive/2007/02/28/659331.ht ml

我的WCF之旅(1):创建一个简单的WCF程序

为了使读者对基于WCF的编程模型有一个直观的映像,我将带领读者一步一步地创建一个完整的WCF应用。本应用功能虽然简单,但它涵盖了一个完整WCF应用的基本结构。对那些对WCF不是很了解的读者来说,这个例子将带领你正式进入WCF的世界。

在这个例子中,我们将实现一个简单的计算服务(CalculatorService),提供基本的加、减、乘、除的运算。和传统的分布式通信框架一样,WCF本质上提供一个跨进程、跨机器以致跨网络的服务调用。在本例中,客户端和服务通过运行在相同的同一台机器上不同进程模拟,图1体现了客户端和服务端进程互相调用的关系。

图1 计算服务应用运行环境

WCF的服务不能孤立地存在,需要寄宿于一个运行着的进程中,我们把承载WCF服务的进程称为宿主,为服务指定宿主的过程称为服务寄宿(Service Hosting)。在我们的计算服务应用中,采用了两种服务寄宿方式:通过自我寄宿(Self-Hosting)的方式创建一个控制台应用作为服务的宿主(寄宿进程为Hosting.exe);通过IIS寄宿方式将服务寄宿于IIS中(寄宿进程为IIS的工作进行W3wp.exe)。客户端通过另一个控制台应用模拟(进程为Client.exe)。接下来,我们就一步一步来构建这样的一个WCF应用。

步骤一:构建整个解决方案

通过VS 2008创建一个空白的解决方案,添加如下四个项目。项目的类型、承载的功能和相互引用关系如下,整个项目在VS下的结构如图2所示。

Contracts:一个类库项目,定义服务契约(Service Contract),引用System.Servi ceMode程序集(WCF框架的绝大部分实现和API定义在该程序集中);

?Services:一个类库项目,提供对WCF服务的实现。定义在该项目中的所有WCF服务实现了定义在Contracts中相应的服务契约,所以Services具有对Contracts项目的引用;

?Hosting:一个控制台(Console)应用,实现对定义在Services项目中的服务的寄宿,该项目须要同时引用Contracts和Services两个项目和System.ServiceMode程序集;?Client:一个控制台应用模拟服务的客户端,该项目引用System.ServiceMode程序集。

图2 计算服务在VS中的结构

步骤二:创建服务契约

WCF采用基于契约的交互方式实现了服务的自治,以及客户端和服务端之间的松耦合。WCF

包含四种类型的契约:服务契约、数据契约、消息契约和错误契约,这里着重于服务契约。从功能上讲,服务契约抽象了服务提供的所有操作;而站在消息交换的角度来看,服务契约则定义了基于服务调用的消息交换过程中,请求消息和回复消息的结构,以及采用的消息交换模式。第4章将提供对服务契约的详细介绍。

一般地,我们通过接口的形式定义服务契约。通过下面的代码,将一个接口ICalculator定义成服务契约。WCF广泛采用基于自定义特性(Custom Attribtue)的声明式编程模式,我们通过在接口上应用System.ServiceModel.ServiceContractAttribute特性将一个接口定义成服务契约。在应用ServiceContractAttribute特性的同时,还可以指定服务契约的名称和命名空间。至于契约名称和命名空间的含义和作用,在本人拙著《WCF技术剖析(卷1)》第4章,在这里我们将契约名称和命名空间设置成CalculatorService和https://www.doczj.com/doc/1218648008.html,/)。通过应用ServiceContractAttribute特性将接口定义成服务契约之后,接口的方法成员并不能自动成为服务的操作。在此方面,WCF采用的是显式选择(Explicit Opt-in)的策略:我们须要在相应的操作方法上面显式地应用OperationContractAttribute特性。

1:using System.ServiceModel;

2:namespace Artech.WcfServices.Contracts

3: {

4: [ServiceContract(Name="CalculatorService",

Namespace="https://www.doczj.com/doc/1218648008.html,/")]

5:public interface ICalculator

7: [OperationContract]

8:double Add(double x, double y);

9:

10: [OperationContract]

11:double Subtract(double x, double y);

12:

13: [OperationContract]

14:double Multiply(double x, double y);

15:

16: [OperationContract]

17:double Divide(double x, double y);

18: }

19: }

步骤三:创建服务

当服务契约成功创建时,我们需要通过实现服务契约来创建具体的WCF服务。WCF服务CalculatorService定义在Services项目中,实现了服务契约接口ICalculator,实现了所有的服务操作。CalculatorService定义如下:

1:using Artech.WcfServices.Contracts;

2:namespace Artech.WcfServices.Services

3: {

4:public class CalculatorService:ICalculator

5: {

6:public double Add(double x, double y)

7: {

8:return x + y;

9: }

10:

11:public double Subtract(double x, double y)

12: {

13:return x - y;

14: }

15:

16:public double Multiply(double x, double y)

17: {

18:return x * y;

19: }

20:

21:public double Divide(double x, double y)

22: {

23:return x / y;

24: }

26: }

步骤四:通过自我寄宿的方式寄宿服务

WCF服务需要依存一个运行着的进程(宿主),服务寄宿就是为服务指定一个宿主的过程。WCF 是一个基于消息的通信框架,采用基于终结点(Endpoint)的通信手段。终结点由地址(Address)、绑定(Binding)和契约(Contract)三要素组成,如图3所示。由于三要素应为首字母分别

为ABC,所以就有了易于记忆的公式:Endpoint = ABC。一个终结包含了实现通信所必需的

所有信息,我们可以这样认识终结点的ABC:

?地址(Address):地址决定了服务的位置,解决了服务寻址的问题,《WCF技术剖析(卷

1)》第2章提供了对地址和寻址机制的详细介绍;

?绑定(Binding):绑定实现了通信的所有细节,包括网络传输、消息编码,以及其他为实现某种功能(比如安全、可靠传输、事务等)对消息进行的相应处理。WCF中具有一系列的系统定义绑定,比如BasicHttpBinding、WsHttpBinding、NetTcpBinding等,《W CF技术剖析(卷1)》第3章提供对绑定的详细介绍;

?契约(Contract):契约是对服务操作的抽象,也是对消息交换模式以及消息结构的定义。

《WCF技术剖析(卷1)》第4章提供对服务契约的详细介绍。

图3 终结点三要素

服务寄宿的目的就是开启一个进程,为WCF服务提供一个运行的环境。通过为服务添加一个或多个终结点,使之暴露给潜给的服务消费者。服务消费者最终通过相匹配的终结点对该服务进行调用。我们可以完全通过代码的方式完成所有的服务寄宿工作,下面的代码体现了通过一个控制台应用对CalculatorService的寄宿:

1:using System;

2:using System.ServiceModel;

3:using System.ServiceModel.Description;

4:using Artech.WcfServices.Contracts;

5:using Artech.WcfServices.Services;

6:namespace Artech.WcfServices.Hosting

7: {

8:class Program

9: {

10:static void Main(string[] args)

11: {

12:using (ServiceHost host = new ServiceHost(typeof(CalculatorService)))

13: {

14: host.AddServiceEndpoint(typeof(ICalculator), new WSHttpBinding(), "http://127.0.0.1:9999/calculatorservice");

15:if (host.Description.Behaviors.Find() == null)

16: {

17: ServiceMetadataBehavior behavior = new ServiceMetadataBehavior(); 18: behavior.HttpGetEnabled = true;

19: behavior.HttpGetUrl = new

Uri("http://127.0.0.1:9999/calculatorservice/metadata");

20: host.Description.Behaviors.Add(behavior);

21: }

22: host.Opened += delegate

23: {

24: Console.WriteLine("CalculaorService已经启动,按任意键终止服务!");

25: };

26:

27: host.Open();

28: Console.Read();

29: }

30: }

31: }

32: }

WCF服务寄宿通过一个特殊的对象完成:ServiceHost。在上面的例子中,基于WCF服务的类型(typeof(CalculatorService))创建了ServieHost对象,并添加了一个终结点。具体的地址为http://127.0.0.1:9999/calculatorservice,采用了WSHttpBinding,并指定了服务契约的类型ICalculator。

松耦合是SOA的一个基本的特征,WCF应用中客户端和服务端的松耦合体现在客户端只须要了解WCF服务基本的描述,而无须知道具体的实现细节,就可以实现正常的服务调用。WCF 服务的描述通过元数据(Metadata)的形式发布出来。WCF中元数据的发布通过一个特殊的服务行为ServiceMetadataBehavior实现。在上面提供的服务寄宿代码中,我们为创建的ServiceHost添加了ServiceMetadataBehavior,并采用了基于HTTP-GET的元数据获取方式,元数据的发布地址通过ServiceMetadataBehavior的HttpGetUrl指定。在调用ServiceHost的Open方法对服务成功寄宿后,我们可以通过该地址获取服务相关的元数据。

在IE地址栏上键入http://127.0.0.1:9999/calculatorservice/metadata,你将会得到以WSDL形式体现的服务元数据,如图4所示。

图4 通过HTTP-GET的方式获取WCF服务的元数据

在进行真正的WCF应用开发时,一般不会直接通过编码的方式进行终结点的添加和服务行为的定义,而是通过配置的方式进行。上面添加终结点和定义服务行为的代码可以用下面的配置代替: 1:

2:

3:

4:

5:

6:

7:

httpGetUrl="http://127.0.0.1:9999/calculatorservice/metadata"/>

8:

9:

10:

11:

12:

name="Artech.WcfServices.Services.CalculatorService">

13:

binding="wsHttpBinding"

contract="Artech.WcfServices.Contracts.ICalculator"/>

14:

15:

16:

17:

对于初学者来说,WCF的配置显得过于复杂,直接对配置文件进行手工编辑不太现实。在这种情况下,可以直接使用VS提供的配置工具。你可以通过VS的工具(Tools)菜单,选择“WCF Service Configuration Editor”子项,开启这样的一个配置编辑器,如图5所示。

如果采用了上诉的配置,服务寄宿代码将会得到极大的精简,只需包含下面几行代码:

1:namespace Artech.WcfServices.Hosting

2: {

3:class Program

4: {

5:static void Main(string[] args)

6: {

7:using (ServiceHost host = new ServiceHost(typeof(CalculatorService))) 8: {

9: host.Opened += delegate

10: {

11: Console.WriteLine("CalculaorService已经启动,按任意键终止服务!");

12: };

13:

14: host.Open();

15: Console.Read();

16: }

17: }

18: }

19: }

图5 如何获得WCF服务配置编辑器

步骤五:创建客户端调用服务

服务被成功寄宿后,服务端便开始了服务调用请求的监听工作。此外,服务寄宿将服务描述通过元数据的形式发布出来,相应的客户端就可以获取这些元数据创建客户端程序进行服务的消费。在VS下,当我们添加服务引用的时候,VS在内部帮我们实现元数据的获取,并借助这些元数据通过代码生成工具(SvcUtil.exe)自动生成用于服务调用的服务代理相关的代码和相应的配置。

在运行服务寄宿程序(Hosting.exe)的情况下,右键点击Client项目,在弹出的上下文菜单中选择“添加服务引用(Add Service References)”,如图6所示的添加服务引用的对话会显示出来。在地址栏上键入服务元数据发布的源地址:

http://127.0.0.1:9999/calculatorservice/metadata,并指定一个命名空间,点击OK按钮,VS为为你生成一系列用于服务调用的代码和配置。

图6 添加服务引用

在一系列自动生成的类中,包含一个服务契约接口、一个服务代理对象和其他相关的类。被客户端直接用于服务调用的是一个继承自ClientBase并实现了CalculatorService接口(CalculatorService为客户端生成的服务契约接口类型)的服务代理类。ClientBase的定义如下所示:

1:namespace Artech.WcfServices.Client.CalculatorServices

2: {

3://其他类型成员

4: [System.Diagnostics.DebuggerStepThroughAttribute()]

5: [https://www.doczj.com/doc/1218648008.html,piler.GeneratedCodeAttribute("System.ServiceModel",

"4.0.0.0")]

6:public partial class CalculatorServiceClient :

System.ServiceModel.ClientBase, Artech.WcfServices.Client.CalculatorServices.CalculatorService {

7:

8:public CalculatorServiceClient() {

9: }

10:

11:public CalculatorServiceClient(string endpointConfigurationName) :

12:base(endpointConfigurationName) {

13: }

14:

15:public CalculatorServiceClient(string endpointConfigurationName, string remoteAddress) :

16:base(endpointConfigurationName, remoteAddress) {

17: }

18:

19:public CalculatorServiceClient(string endpointConfigurationName,

System.ServiceModel.EndpointAddress remoteAddress) :

20:base(endpointConfigurationName, remoteAddress) {

21: }

22:

23:public CalculatorServiceClient(System.ServiceModel.Channels.Binding binding, System.ServiceModel.EndpointAddress remoteAddress) :

24:base(binding, remoteAddress) {

25: }

26:

27:public double Add(double x, double y) {

28:return base.Channel.Add(x, y);

29: }

30:

31:public double Subtract(double x, double y) {

32:return base.Channel.Subtract(x, y);

33: }

34:

35:public double Multiply(double x, double y) {

36:return base.Channel.Multiply(x, y);

37: }

38:

39:public double Divide(double x, double y) {

40:return base.Channel.Divide(x, y);

41: }

42: }

我们可以创建CalculatorServiceClient对象,执行相应方法调用服务操作。客户端进行服务调用的代码如下:

1:using System;

2:using Artech.WcfServices.Client.CalculatorServices;

3:namespace Artech.WcfServices.Client

4: {

5:class Program

6: {

7:static void Main(string[] args)

8: {

9:using (CalculatorServiceClient proxy = new CalculatorServiceClient())

10: {

11: Console.WriteLine("x + y = {2} when x = {0} and y = {1}", 1, 2, proxy.Add(1, 2));

12: Console.WriteLine("x - y = {2} when x = {0} and y = {1}", 1, 2, proxy.Subtract(1, 2));

13: Console.WriteLine("x * y = {2} when x = {0} and y = {1}", 1, 2, proxy.Multiply(1, 2));

14: Console.WriteLine("x / y = {2} when x = {0} and y = {1}", 1, 2, proxy.Divide(1, 2));

15: }

16: }

17: }

18: }

运行后输出:

x + y = 3 when x = 1 and y = 2

x - y = -1 when x = 1 and y = 2

x * y = 2 when x = 1 and y = 2

x / y = 0.5 when x = 1 and y = 2

客户端通过服务代理对象进行服务的调用,上面的例子通过创建自动生成的、继承自ClientBase的类型对象进行服务调用。实际上,我们还具有另外一种创建服务代理的方法,就是通过ChannelFactory。此外,WCF采用基于契约的服务调用方法,从上面的例子我们也可以看到,VS在进行服务引用添加的过程中,会在客户端创建一个与服务端等效的服务契约接口。在我们的例子中,由于服务端和客户端都是在同一个解决方案中,完全可以让服务端和客户端引用相同的契约。

为了演示这种场景,我们将添加的服务引用移除,并为Client项目添加对Contracts项目的引用。借助于这个服务契约,并通过ChannelFactory创建服务代理对象,直接

进行相应的服务调用。下面的代码演示了基于ChannelFacotory进行服务代理的创建和服务调用的方式。

1:using System;

2:using System.ServiceModel;

3:using Artech.WcfServices.Contracts;

4:namespace Artech.WcfServices.Client

5: {

6:class Program

7: {

8:static void Main(string[] args)

9: {

10:using (ChannelFactory channelFactory = new

ChannelFactory(new WSHttpBinding(),

"http://127.0.0.1:9999/calculatorservice"))

11: {

12: ICalculator proxy = channelFactory.CreateChannel();

13:using (proxy as IDisposable)

14: {

15: Console.WriteLine("x + y = {2} when x = {0} and y = {1}", 1, 2, proxy.Add(1, 2));

16: Console.WriteLine("x - y = {2} when x = {0} and y = {1}", 1, 2, proxy.Subtract(1, 2));

17: Console.WriteLine("x * y = {2} when x = {0} and y = {1}", 1, 2, proxy.Multiply(1, 2));

18: Console.WriteLine("x / y = {2} when x = {0} and y = {1}", 1, 2, proxy.Divide(1, 2));

19: }

20: }

21: }

22: }

23: }

由于终结点是WCF进行通信的唯一手段,ChannelFactory本质上是通过指定的终结点创建用于进行服务调用的服务代理。在上面的代码中,在创建ChannelFactory的时候再在构造函数中指定终结点的相关要素(契约通过范型类型表示,地址和绑定则通过参数指定)。在真正的WCF应用中,大都采用配置的方式进行终结点的定义。我们可以通过下面的配置指定终结点的三要素,并为相应的终结点指定一个终结点配置名称(calculatorservice)。

1:

2:

3:

4:

5:

binding="wsHttpBinding"contract="Artech.WcfServices.Contracts.ICalculator"

name="calculatorservice"/>

6:

7:

8:

那么在创建ChannelFactory的时候,就无须再指定终结点的绑定和地址了,而只须制定对应的终结点配置名称。

1:using System;

2:using System.ServiceModel;

3:using Artech.WcfServices.Contracts;

4:namespace Artech.WcfServices.Client

5: {

6:class Program

7: {

8:static void Main(string[] args)

9: {

10:using (ChannelFactory channelFactory = new

ChannelFactory( "calculatorservice"))

11: {

12://省略代码

13: }

14: }

15: }

16: }

步骤六:通过IIS寄宿服务

上面演示了通过自我寄宿的方式寄宿服务,现在我们来演示如何将WCF服务寄宿到IIS中。寄宿IIS的服务寄宿比较简单,基本上包含两个步骤:为WCF服务创建.svc文件和创建IIS虚拟目录。

1、为WCF服务创建.svc文件

我们知道,每一个https://www.doczj.com/doc/1218648008.html, Web服务都具有一个.asmx文本文件,客户端通过访问.asmx 文件实现对相应Web服务的调用。与之类似,每个WCF服务也具有一个对应的文本文件,其文件扩展名为.svc。基于IIS的服务寄宿要求相应的WCF服务具有相应的.svc文件,.svc文件部署于IIS站点中,对WCF服务的调用体现在对.svc文件的访问上。

.svc文件的内容很简单,仅仅包含一个ServiceHost指令(Directive),该指令具有一个必须的Service属性和一些可选的属性。所以最简单的.svc仅仅具有一个包含Service属性(该属性指明了相应的WCF服务的有效类型)的ServiceHost指令。CalculatorService对应

的.svc如下所示,我们把该.svc放在Services项目的根目录下,并将文件命名为CalculatorService.svc。

1: <%@ServiceHost Service="Artech.WcfServices.Services.CalculatorService"%>

2、为WCF服务创建虚拟目录

和一般的寄宿于IIS下的Web应用一样,需要在IIS下创建相应的虚拟目录。在本应用中,为

了方便,我们直接把Services项目的根目录映射为IIS虚拟目录,并把该虚拟目录的命名为WcfServices。

接下来需要为通过IIS寄宿的CalculatorService创建配置文件,我们只须在Services的根目录下创建一个Web.config,将WCF相应的配置添加到该配置文件中即可。Web.config所有配置内容如下所示,可以看出,这基本上和上面通过自我寄宿方式定义的配置一致。唯一不同的是在添加的终结点中无须指定地址,因为.svc所在的地址就是服务的地址。也就是说,CalculatorService的地址为http://127.0.0.1/wcfservices/calculatorservice.svc。你可以通过http://127.0.0.1/wcfservices/calculatorservice.svc?wsdl得到相应的元数据。由于WSHttpBinding在默认情况下采用Windows认证,所以在IIS中将Windows集成认证

开启。

1:

2:

3:

4:

5:

6:

7:

8:

9:

10:

11:

12:

name="Artech.WcfServices.Services.CalculatorService">

13:

contract="Artech.WcfServices.Contracts.ICalculator"/>

14:

15:

16:

17:

由于在创建Services项目的时候,我们并不曾引用System.ServiceMode程序集,所以须要加上这样一个引用。此外,一个Web应用在运行的时候会默认从位于根目录下的Bin目录加载

程序集,而默认的情况下,我们编译后的程序集会自动保存到Bin\Debug|Release目录下,

所以须要通过VS修改Services项目属性,将编译输出目录设置成Bin。

客户端仅仅须要修改终结点的地址,从而转向对寄宿于IIS下的CalculatorService的访问,

该地址即为.svc文件的网络地址:http://127.0.0.1/wcfservices/calculatorservice.svc。 1:

2:

3:

4:

5:

binding="wsHttpBinding"contract="Artech.WcfServices.Contracts.ICalculator"

name="calculatorservice"/>

6:

7:

8:

分类: [01]

WCF实际上是构建了一个框架,这个框架实现了在互联系统中各个Application之间如何通信。使得Developers和Architect在构建分布式系统中,无需在考虑如何去实现通信相关的问题,更加关注与系统的业务逻辑本身。而在WCF Infrastructure中,各个Application之间的通信是由Endpoint来实现的。

Endpoint的结构

Endpoint包含以下4个对象:

?Address: Address通过一个URI唯一地标识一个Endpoint,并告诉潜在的WCF serv

ice的调用者如何找到这个Endpoint。所以Address解决了Where to locate the WC

F Service?

?Binding: Binding实现在Client和Service通信的所有底层细节。比如Client与Servi

ce之间传递的Message是如何编码的——text/XML, binary,MTOM;这种Message 的传递是采用的哪种Transport——TCP, Http, Named Pipe, MSMQ; 以及采用怎样的机制解决Secure Messaging的问题——SSL,Message Level Security。所以Bi nding解决的是How to communicate with service?

?Contract: Contract的主要的作用是暴露某个WCF Service所提供的所有有效的Func tionality。从Message Exchange的层面上讲,Contract实际上是抱每个Operation 转化成为相对应的Message Exchange Pattern——MEP(Request/Response;On e-way;Duplex)。所以Contract解决的是What functionalities do the Service provide?

? Behavior: Behavior的主要作用是定制Endpoint在运行时的一些必要的Behavior。

比如Service 回调Client的Timeout;Client采用的Credential type;以及是否支持Transaction等。

当我们Host一个WCF Service的时候,我们必须给他定义一个或多个Endpoint,然后service 通过这个定义的Endpoint进行监听来自Client端的请求。当我们的Application需要调用这个Service的时候,因为Client 和Service是通过Endpoint的进行通信的,所以我们必须为我们的Application定义Client端的Endpoint。只有当Client的Endpoint和Service端某个Endpoint相互匹配(Service端可以为一个Service定义多个Endpoint),Client端的请求才能被Service端监听到。也就是说,我们只有在Client具有一个与Service端完全匹配的Endpoint,我们才能调用这个Service。而这种匹配是比较严格的,比如从匹配Address 方面,Client端和Service端的Endpoint Address不仅仅在URI上要完全匹配Service,他们的Headers也需要相互匹配。对于Binding, 一般地,Client需要有一个与Service端完全一样的Binding,他们之间才能通信。

Sample

首先给一个Sample,以便我们对在WCF Service Aplication中如何定义Endpoint有一个感性的认识。整个Solution的结构参照下图,我的上一篇Blog([原创]我的WCF之旅(1):创建一个简单的WCF程序)中有详细的介绍。你也可以通过后面的Link下载相应的Source Code (https://www.doczj.com/doc/1218648008.html,/files/artech/Artech.WCFService.zip )

1. Service Contract:

Artech..WCfService.Contract/ServiceContract/IGeneralCalculator.cs using System;

using System.Collections.Generic;

using System.Text;

using System.ServiceModel;

namespace Artech.WCFService.Contract

{

[ServiceContract]

public interface IGeneralCalculator

{

[OperationContract]

double Add(double x, double y);

}

}

2. Service: Artech.WCFSerice.Service/GeneralCalculatorService.cs using System;

using System.Collections.Generic;

using System.Text;

using Artech.WCFService.Contract;

namespace Artech.WCFService.Service

{

public class GeneralCalculatorService:IGeneralCalculator

{

IGeneralCalculator Members

}

}

3. Hosting: Artech.WCFService.Hosting/Program.cs

using System;

using System.Collections.Generic;

using System.Text;

using System.ServiceModel;

using Artech.WCFService.Contract;

using Artech.WCFService.Service;

using System.ServiceModel.Description;

namespace Artech.WCFService.Hosting

{

class Program

{

static void Main(string[] args)

{

//HostCalculatorServiceViaCode();

HostCalculatorSerivceViaConfiguration();

}

///

/// Hosting a service using managed code without any configuraiton infor mation.

/// Please note that the related configuration data should be removed befo re calling the method.

///

static void HostCalculatorServiceViaCode()

{

Uri httpBaseAddress = new Uri("http://localhost:8888/generalCalculato r");

Uri tcpBaseAddress = new Uri("net.tcp://localhost:9999/generalCalcula tor");

using (ServiceHost calculatorSerivceHost = new ServiceHost(typeof(Ge neralCalculatorService), httpBaseAddress, tcpBaseAddress))

{

BasicHttpBinding httpBinding = new BasicHttpBinding();

NetTcpBinding tcpBinding = new NetTcpBinding();

calculatorSerivceHost.AddServiceEndpoint(typeof(IGeneralCalculator ), httpBinding, string.Empty);

calculatorSerivceHost.AddServiceEndpoint(typeof(IGeneralCalculator ), tcpBinding, string.Empty);

ServiceMetadataBehavior behavior = calculatorSerivceHost.Descripti on.Behaviors.Find();

{

if(behavior == null)

{

behavior = new ServiceMetadataBehavior();

behavior.HttpGetEnabled = true;

calculatorSerivceHost.Description.Behaviors.Add(behavior);

}

else

{

behavior.HttpGetEnabled = true;

}

}

calculatorSerivceHost.Opened += delegate

{

Console.WriteLine("Calculator Service has begun to listen "); };

calculatorSerivceHost.Open();

Console.Read();

}

}

static void HostCalculatorSerivceViaConfiguration()

{

using (ServiceHost calculatorSerivceHost = new ServiceHost(typeof(Ge neralCalculatorService)))

{

calculatorSerivceHost.Opened += delegate

{

Console.WriteLine("Calculator Service has begun to listen "); };

calculatorSerivceHost.Open();

Console.Read();

}

}

}

}

4. Service.svc: http://localhost/WCFService/ GeneralCalculatorService.svc

<%@ ServiceHost Language="C#" Debug="true" Service="Artech.WCFService.S ervice.GeneralCalculatorService" %>

5. Client: Artech.WCFService.Client/ GeneralCalculatorClient.cs & Program.cs

using System;

using System.Collections.Generic;

using System.Text;

using System.ServiceModel;

using System.ServiceModel.Channels;

using Artech.WCFService.Contract;

namespace Artech.WCFService.Client

{

class GeneralCalculatorClient:ClientBase,IGeneralCalcul ator

{

public GeneralCalculatorClient()

: base()

{ }

public GeneralCalculatorClient(string endpointConfigurationName)

: base(endpointConfigurationName)

{ }

WCF教程(一)

跟我一起从零开始学WCF(1)
WCF概述
徐长龙 MSDN 特邀讲师 vsts_china@https://www.doczj.com/doc/1218648008.html,

加速企业解决方案部署尽在
资源和利益
? 用于解决方案开发的集中资源 用于解决方案开发的集中资源:资源包括指向测试工具、开发 资源包括指向测试工具 开发 人员 SDK、技术论坛、联机培训等的链接,微软全球技术支持 中心( (GTSC) )的邮件技术支持。 ? 对市场调查的访问权限:您可以使用这些宝贵信息来识别您当 前的客户或未来客户的特定需求。 ? 认证徽标计划:该徽标可以向客户证明您所具有的优秀技术。 ? 市场营销和销售支持
https://www.doczj.com/doc/1218648008.html, h O

Metro – ISV领航计划
最先应用微软最新技术 提升ISV 提升 ISV竞争优势和商业价值 竞争优势和商业价值
? Metro 提供了结构化的支持来帮助ISV进行新技术的评估和 部署 部署: Discover – 参与前沿技术培训 – 评估最新的微软技术及产品 Release Learn – 获取微软Beta版产品的技术支持 – 联络全球开发人员和架构师社区 – 与世界级的商务和技术社区分享最先 Develop 部署的经验

收听本次课程需具备的条件
? 熟悉Web Service编程 ? 熟悉Visual Studio 2005/2008 ? 熟悉分布式应用程序开发
Level 200

本次课程内容包括 ? 什么是WCF? ? WCF背景介绍

WCF服务编程

序 序 (1) 前言 (8) 第1章WCF基础 (13) 什么是WCF (14) 服务 (15) 服务的执行边界 (16) WCF与位置透明度 (17) 地址 (18) TCP地址 (19) HTTP地址 (20) IPC地址 (20) MSMQ地址 (20) 对等网地址 (21) 契约 (21) 服务契约(Service Contract) (21) 数据契约(Data Contract) (21) 错误契约(Fault Contract) (22) 消息契约(Message Contract) (22) 服务契约 (22) 应用ServiceContract特性 (25)

名称与命名空间 (28) 托管 (30) IIS托管 (30) 使用Visual Studio 2005 (31) Web.Config文件 (32) 自托管 (32) 使用Visual Studio 2005 (35) 自托管与基地址 (35) 托管的高级特性 (38) ServiceHost类 (39) WAS托管 (41) 绑定 (41) 标准绑定 (42) 基本绑定(Basic Binding) (43) TCP绑定 (43) 对等网绑定 (43) IPC绑定 (43) WS联邦绑定(Federated WS Binding) (44) WS双向绑定(Duplex WS Binding) (44) MSMQ绑定 (44) 格式与编码 (44) 选择绑定 (45)

使用绑定 (47) 终结点 (47) 管理方式配置终结点 (48) 绑定配置 (52) 编程方式配置终结点 (53) 绑定配置 (56) 元数据交换 (56) 编程方式启用元数据交换 (59) 元数据交换终结点 (62) 编程方式添加MEX终结点 (64) 简化ServiceHost类 (65) 元数据浏览器 (71) 客户端编程 (71) 生成代理 (72) 管理方式配置客户端 (76) 绑定配置 (78) 生成客户端配置文件 (78) 进程内托管配置 (79) SvcConfigEditor编辑器 (80) 创建和使用代理 (81) 关闭代理 (82) 调用超时 (84)

WCF实例

8.2Hello, World实例 本实例与传统入门教材相同,仍然以输出一个“Hello,World”字符串开始。实例将新建2个项目,第一个项目名为“HelloWorldService”,它提供WCF服务,并且以开发环境方式暴露一个端口供客户端调用;另外一个项目叫“HelloWorldClient”,它调用WCF服务方法,并输出返回值。 本实例的运行结果如图所示: 8.2.1创建WCF服务端程序 1)打开Microsoft Visual Studio 2010; 2)选择菜单>文件>新建>项目; 3)在弹出的“新建项目”对话框中展开左边的“已安装的模板”>Visual C#; 4)选择“WCF”; 5)在对话框右边选择“WCF Service Application“; 6)在对话框下部的“项目名“中输入”HelloWorldService“,在位置中输入” d:\Exercise “,在解决方案名称输入”WcfSample“,确保选中”Create directory for solution “,确保未选中”Add to source control“,设置后的界面如下:

7)点击“OK“按钮,VS2010已自动建立了一个WCF Service Application,并且为我们自动打开了Service1.svc.cs文件; 8)打开“Solution Explorer”;(VS2010默认打开,位置在VS2010桌面的右边,如果VS2010没有打开,请使用快捷键Ctrl + W,S打开) 9)在“Solution Explorer”中展开“HelloWorldService”; 10)双击“IService1.cs”文件; 11)用下面的代码 ///

/// 提供一个WCF服务方法 /// /// 返回“Hello, World!” [OperationContract] //声明为“OperationContract”的方法将暴露在WCF服务器上 string GetHelloWorld(); 替换第22行的注释 // TODO: Add your service operations here 知识点: “ServiceContract”代表服务契约,表示IService1接口是一个WCF服务,这样,客户端就可以访问这个接口和它内部有效的方法了。 “OperationContract”代表操作契约,表示GetHelloWorld方法是服务契约中的一个方法,只有声明为“OperationContract”的方法才会被公开在WCF服务中。如果服务中没有任何一个方法声明为“OperationContract”,那么这个服务将没有任何意义。

七步通使用WCF Service流程

七步通使用WCF Service流程 Service对于编程人来说并不陌生,学习了很长时间的WCF,我们现在就WCF Service 一起来和大家分析探讨一下。熟悉Web Service开发的程序员对添加服务引用应该并不陌生。在创建某个服务的客户端程序时,并不需要从头开始编写客户端的底层通信和交互代码,可以通过输入服务地址来添加服务来让Visual Studio生成客户端代理,这样访问服务就像访问本地组件一样,而不需要去关心通信的细节。 如果创建的客户端程序项目和服务程序项目处在同一个解决方案里(很多开发者在开发服务时,也会同步开发客户端程序),还可以通过Visual Studio来帮助我们“发现(Discovery)”服务,并添加服务引用。现在开发WCF Service的程序员也可以得益于这些功能了。如果从WCF Service Library (或者WCF 节点下的Sequential Workflow Service Library 和 State Machine Workflow) 项目模板创建一个项目,那么这些功能就已经具备。 下面我们来看一下如何使用: 1.创建一个客户端程序,可以是一个Windows Console程序。 2.在同一解决方案里添加一个WCF Service Library。如图: 3.Build WcfServiceLibrary1。 4.右键ConsoleApplication1,在上下文菜单中选择“添加服务引用“(Add Service Reference). 5.此时可以看到一个对话框:

6.如果已经知道服务的地址,可以直接在Address栏输入地址来添加服务,单击“Go”。可以找到这个地址对应的服务。 7.如果想添加同一个解决方案里的服务,可以先单击“发现”来寻找服务。找到服务后,选中需要在客户端程序生成引用的服务,然后单击确定,这个时候WcfSvcHost就会自动启动来HOST服务。几秒以后,可以看到客户端自动生成了服务代理代码: 通过上面的步骤在客户端完成了添加服务引用,现在可以访问服务了,只需要通过下面两行代码就可以调用服务端的一个方法: 1.ServiceReference1.Service1Client client = new ServiceReference1.Serv ice1Client(); 2.client.GetData(0);

Win7下使用IIS托管WCF服务

Win7下使用IIS托管WCF服务 第一步,确保Win7正确安装了IIS。 操作步骤: 1.打开控制面板-程序和功能-点击左侧“打开或关闭Windows功能”,在弹出框中选中 “Internet信息服务”,需要注意的是有的需要将其展开,选中相关项。 2.在浏览器中输入http://localhost,如果出现了IIS启动界面,即表示IIS安装成功。 第二步,在进行IIS托管WCF服务之前,先建立一个https://www.doczj.com/doc/1218648008.html,程序试下。 由于Win7+VS2010使用的是.Net 4.0,所以需要确保注册了https://www.doczj.com/doc/1218648008.html, 4.0。 操作步骤: 1.进入C:\Windows\System32找到cmd.exe,右键“以管理员身份运行”,然后在控制台输 入:cd C:\Windows\https://www.doczj.com/doc/1218648008.html,\Framework\v4.0.30319切换到该目录 2.然后输入:aspnet_regiis.exe –i,就会看到正在注册,以及注册成功的提示信息。 备注:最好使用控制台来进行https://www.doczj.com/doc/1218648008.html,的注册,其实也可以直接以管理员身份运行aspnet_regiis.exe,但是会看不到是否成功的提示! 第三步:创建解决方案,并发布https://www.doczj.com/doc/1218648008.html,网站 操作步骤: 1.创建一个默认的https://www.doczj.com/doc/1218648008.html,网站,不用更改其中任何东西。 2.在项目上,右键“属性页”,在“启动选项”中的“特定页”和服务器,进行如下设置: 需要注意的是,这时如果你在项目上右键-在浏览器中查看,会发现不能访问。 3.鼠标右键-发布网站,出现如下图所示对话框:

点击“目标位置”进入如图对话框: 选择“文件系统”,即表示你要将你的网站发布到的本地计算机的位置,在第四步建立网站的时候会引用。 备注:由于,我们没有修改代码,应该发布会很顺利。

使用WCF实现SOA面向服务编程

作者: 风尘浪子来源: 博客园发布时间: 2011-04-12 11:07 阅读: 3121 次原文链接全屏阅读 [收藏] SOA本身就是一种面向企业级服务的系统架构,简单来说,SOA就是一种进行系统开发的新的体系架构,在基于SOA架构的系统中,具体应用程序的功能是由一些松耦合并且具有统一接口定义方式的组件(也就是service)组合构建起来的。因此,基于SOA的架构也一定是从企业的具体需求开始构建的。但是,SOA和其它企业架构的不同之处就在于SOA提供的业务灵活性。业务灵活性是指企业能对业务变更快速和有效地进行响应、并且利用业务变更来得到竞争优势的能力。对企业级架构设计师来说,创建一个业务灵活的架构意味着创建一个可以满足当前还未知的业务需求的IT架构。使用WCF实现SOA,正好可以利用WCF的灵活性,把业务层封装,发布为Web服务。这样可以降低系统的耦合度,加大对未知业务的扩展性。

Web服务本来就是没有区分代码的,在这个例子里在下多开发了一个Service Interface目的是为了使系统更易于管理。在开发期间,Service是不断更改的,如果在UI层上直接调用服务层,那更改将会是频密的,所以在这里在下开发一个Service Interface层目的是为了把WSDL集成在同一个DLL程序集里面,进行统一修改。最后UI层只要直接调用Service Interface,就可以对系统直接进行操作。要以不同开发工具来实现Service Interface,这个的代价并不大,开销是可以承担的。下面附上最简单的例子,希望有经验的高手给予点评,有不妥的地方请多加指教。

WCF服务如何获取客户端在线用户

本文和大家讲下WCF服务如何获取客户端在线用户数量?你没有关注过这个问题吧,一起来看下本文的实现方法。【1】问题分析: 这个问题,在WCF服务编程中也非常的常见,以下是对于这个问题的不同描述形式,但是本质基本类似:WCF如何获取在线客户端数量? WCF如何获取在线用户列表? WCF服务如何知道客户端离线? 如何判断WCF离线客户端? 或许还有别的提法,但是基本都是差不多的。 此类问题出现在回调、双工通信的场景中比较多,有的程序具备类似聊天室的功能,就比较在乎客户端的离线事件。 【2】解决办法: 这里服务端对于客户端在线的判断,也是固定的,基本是基于对通道状态的判断,来实现对于客户端在线状态的判断。 实现的思路基本就是,在服务端维护一个在线客户端Channel的列表List,然后每次通道关闭(Closed)或者出错(Faulted)调用特定的方法来移调通道。 这里另外一个需要注意的地方就是多线程并发的问题。 因为在线用户通道list是一个静态变量,多线程访问的时候,需要注意互斥操作的问题。 【3】示例代码: 这里的代码页比较简单,基本思路: //回调通道列表,也可以用来保持 private static List channelsList = new List(); private static Object thisLock = new Object(); 另外服务默认的是PerSession实例模式,对于单个客户端Proxy实例只有一个服务。 【3.1】服务端: 这里最重要的就是一个绑定一个方法给Closed事件, OperationContext.Current.Channel.Closed += new EventHandler(ShowOffLine); 全部的代码如下: Code [https://www.doczj.com/doc/1218648008.html,]using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.ServiceModel; using System.ServiceModel.Description; using System.Runtime.Serialization; using System.Threading; //ServiceContract 属性以及Indigo 使用的所有其他属性均在System.ServiceModel 命名空间中定义, //因此本例开头使用using 语句来引用该命名空间。 namespace WCFService { //1.回调服务契约,由于回调方法在客户端执行,因此无须添加ServiceContractAttribute。对于回调操作,服务器无须获取其返回信息,因此添加IsOneWay=true 特性参数。 public interface IWCFServiceCallBack { //操作契约 [OperationContract(IsOneWay=true)]// void SayHelloCalllBack(); } //2.服务契约,指定CallbackContract 回调契约。 [ServiceContract(CallbackContract = typeof(IWCFServiceCallBack))]

一个完整的WCF服务的发布与测试过程

使用VS自带的WCFSVCHost(WCF服务主机)发布WCF服务,时刻开发人员测试使用。下面我们来看一下如何在IIS中部发布一个WCF服务。 环境是VS 2008 (公司电脑没有安装VS2010)^_^ 我们从头开始,不写代码,完全的配置,会收获不小。 新建一个WCF 服务库 建立一个WCF服务应用程序

结果如下 删除掉WCF程序中不需要的默认文件,如下图

为WcfService1项目添加WcfServiceLibrary1的引用,如下图。 修改声明指示内容,让这个Service.svc文件的后台代码指向我们创建的WCF服务库项目--WcfServiceLibrary1项目中的服务类,改后的代码如下: <%@ ServiceHost Language="C#" Debug="true" Service="WcfServiceLibrary1.Service1" %> Ctrl+Shift+B 编译一下解决方案,配置工具用的反射,先编译才行 此时我们的WCF服务站点并不能把WCF服务库中的服务和终结点发布出来,还需要我们对web.config进行一系列的配置工作。 右键我们要配置的Web.Config文件,编辑WCF配置

在弹出的服务配置窗口中,把Service1服务指定到WCF服务库的WcfServiceLibrary1.dll 中的WcfServiceLibrary1.Service1服务类上。

再把其中的一个对外终结点的Contract设为WCF服务库的WcfServiceLibrary1.dll中的WcfServiceLibrary1.IService1服务契约上。

wcf服务器和客户端创建

一、开发环境 操作系统:Windows 7 开发环境:VS2013 编程语言:C# IIS版本:10.0.0.0 二、添加WCF服务、Internet Information Services(IIS) 1、进入“控制面板”,打开“程序和功能”,点击左上角的“启用或关闭Windows功能”后,在“.NET Framework 4.6 高级服务”中的子节点选中“WCF 服务”,如下图所示: 2、再找到“Internet Information Services”,同样选中该节点,如下图所示:

3、点击“确定”按钮以便安装这些服务与组件,等待完成安装即可。 三、新建一个WCF服务库 1、使用VS2015新建一个WCF服务库,并将项目名称改为“MyWCFService”,如下图所示: 3、将鼠标移到解决方案资源管理器中项目“MyWCFService”上并右击鼠标,弹出上下文菜单,在菜单中选中“发布”后,弹出下图所示的“发布WCF服务”对话框,如下图所示: 在目标位置选择“D:\WCF”,其他按默认,点击“发布”按钮,即可在“D:\WCF”文件夹里生成

如下图所示的文件: 四、新建一个WCF服务网站 1、打开控制面板-管理工具

2.点击打开IIS,右键点击网站,新建一个网站,网站名称设置为“MyWCFService”,物理地址选择“D:\WCF”,端口从默认的80改为81,如下图所示:

3点击确定后,即新建一个WCF服务网站。 五、服务器程序编辑(编辑完成后需要再次发布) 1、点击解决方案下的server1.Cs—GeteData 2、在此处添加程序 六、创建客户端 1、新建一个Windows窗口客户端 2、在解决方案下的引用点击右键,添加服务器引用

WCF客户端动态设置WCF服务器主机

WCF客户端动态设置WCF服务器主机的地址的方法参考,可以连接多个相同WCF主机的方法 最近做一个项目,需要在客户端灵活配置连接到哪个服务器的功能,例如客户端是一个,现在想连接A服务器就连A服务器,想连接B服务器就连接B服务器,当然不需要手动修改配置文件,直接通过程序来实现WCF目标主机的配置功能。 参考核心代码如下: //-------------------------------------------------------------------- // All Rights Reserved , Copyright (C) 2011 , Hairihan TECH, Ltd. //-------------------------------------------------------------------- using System.ServiceModel; namespace DotNet.WCFClient { using DotNet.IService; using DotNet.Utilities; ///

/// ServiceFactory ///本地服务的具体实现接口 ///

///修改纪录 /// /// 2011.07.03 版本:2.0 JiRiGaLa 可以动态指定服务器地址的调用方法。 /// 2009.09.20 版本:1.0 JiRiGaLa 创建。 /// ///版本:2.0 /// /// ///JiRiGaLa ///2011.07.03 /// ///

public class ServiceFactory : IServiceFactory { private string host = string.Empty; /// ///主机地址 /// Host = "192.168.0.122"; /// public string Host { get

WCF入门程序

WCF教程系列(1)-创建第一个WCF程序 作为微软技术.net 3.5的三大核心技术之一的WCF虽然没有WPF美丽的外观 但是它却是我们开发分布式程序的利器 但是目前关于WCF方面的资料相当稀少 希望我的这一系列文章可以帮助大家尽快入门 下面先介绍一下我的开发环境吧 操作系统:windows vista business版本 编译器:Visual Studio 2008(英文专业版) WCF的三大核心是ABC 也就是A代表Address-where(对象在哪里) B代表Binding-how(通过什么协议取得对象) C代表Contact(契约)-what(定义的对象是什么,如何操纵) 其他的理论知识大家可以参见《Programming WCF Service》 或者今年3月份刚刚出版的《Essential Windows Commmunication Foundation》 现在用In Action的方式来手把手教大家创建第一个WCF程序

首先如下图所示创建一个空的解决方案 接下来右键点击解决方案HelloWCF选择Add->New Project并选择Console Application模板并选择名为项目名为Host(服务器端)

接下来右键点击Host项目选择Add->New Item并选择Webservice模板(文件命名为HelloWCFService) 将创建三个文件IHelloWCFService.cs,HelloWCFService.cs以及 App.config文件 IHelloWCFService.cs代码如下 using System.ServiceModel; namespace Host { [ServiceContract] public interface IHelloWCFService

WCF常用的宿主

导语: 前一段时间开始学习WCF,尽管MSDN和网上的资料很多,但是由于刚开始接触WCF 且学习资料不够详尽,所以弄的一头雾水,不知其中所表达的思想,经过这段时间的学习,终于搞明白了WCF常用的宿主。现在把学习到的知识记录下来,供以后参考,也希望能为WCF初学者带来一些帮助。 步骤: 一、定义消息 消息的语义是指:服务中使用的数据对象。 创建类库项目WCFMessage:开始-程序-Microsoft Visual Studio 2010-Microsoft Visual Studio 2010-文件-新建-项目-VisualC#-Windows-类库,解决方案名称:WCFHost,名称:WCFMessage。 引入新的类库:System.Runtime.Serialization.dll 创建类Person:删除项目自动生成的Class1.cs,新建一个Person类,代码如下: using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Runtime.Serialization; namespace WCFMessage { [DataContract] public class Person { [DataMember] public string Id; [DataMember] public string Name; [DataMember] public int Age; } } 二、定义服务协定 服务协定的语义是指:定义服务的接口。

WCF 服务编程

WCF 服务编程(第三版)学习笔记 一、第一章WCF基础 (一)什么是WCF(What Is WCF?) WCF(之前的版本名为“Indigo”)是使用托管代码建立和运行面向服务(Service Oriented)应用程序的统一框架。它使得开发者能够建立一个跨平台的安全、可信赖、事务性的解决方案, 且能与已有系统兼容协作。WCF是微软分布式应用程序开发的集大成者,它整合了.Net平台 下所有的和分布式系统有关的技术,例如.Net Remoting、ASMX、Enterprise Service、WSE、 和MSMQ。以通信(Communication)范围而论,它可以跨进程、跨机器、跨子网、企业网 乃至于Internet;以宿主程序而论,可以以https://www.doczj.com/doc/1218648008.html,,EXE,WPF,Windows Forms,NT Service,COM+作为宿主(Host)。WCF可以支持的协议包括TCP,HTTP,跨进程以及自定义,安全 模式则包括SAML,Kerberos,X509,用户/密码,自定义等多种标准与模式。也就是说,在 WCF框架下,开发基于SOA的分布式系统变得容易了,微软将所有与此相关的技术要素都包 含在内,掌握了WCF,就相当于掌握了叩开SOA大门的钥匙。 WCF绝大部分功能都包含在一个单独的程序集System.ServiceModel.dll中,命名空间:System.ServiceModel。 (二)服务(Service) 服务是一组公开功能的集合。服务是不透明的,客户端并不知道服务的内部实现细节;通过公开元数据的方式描述可用的功能及服务采用的通信。元数据可以预先定义,它与具体的技 术无关(Technology-Neutral),如采用基于HTTP-GET方式的WSDL或符合元数据的任何交 换协议。 (三)地址(Addresses) WCF中每一个服务都有一个地址。地址包含两个重要元素:服务位置与传输协议(Transport-Protocol)或用于服务通信的传输样式(Transport-Scheme)。服务位置包含目 标主机名、站点(或者是网站)、通信端口、管道(或者是队列),以及一个可选的特定路径或 URI(Universal Resource Identifie 统一资源标识)。WCF支持下列传输协议: ●HTTP/HTTPS ●TCP ●IPC ●Peer network ●MSMQ ●Service bus 基地址格式: 【传输协议】://【机器或域名】【:可选端口】 例:net.tcp://localhost:8000/MyService (可以将地址net.tcp://localhost:8000/MyService读做“采用TCP协议访问 localhost机器,MyService服务在8000端口处等待用户的调用) TCP地址(默认端口808): TCP地址采用net.tcp协议进行传输,通常它还包括端口。 例:net.tcp://localhost:8002/MyService

WCF服务以控制台程序为宿主时Silverlight的跨域访问问题

WCF服务以控制台程序为宿主时的跨域访问问题 前几天研究SilverLight时碰到了这个问题,本以为很轻松的试验结果很不顺利,查了很多资料才解决了这个问题,在此把解决问题的方法写出来,也方便其它朋友借鉴。 问题是这样产生了,我在测试SilverLight时为了测试与WCF的通讯,创建了一个控制台的应用程序做为WCF服务的宿主程序。 同时创建了一个SilverLight应用程序和一个承载SilverLight的Web程序. 解决方案如图:

控制台程序: 1.添加WCF服务 命名为WCFService.cs,并添加服务,代码如下: namespace WCFBase { // 注意: 如果更改此处的类名"WCFService",也必须更新App.config 中对"WCFService" 的引用。 public class WCFService : IWCFService

{ public int DoWork(int a,int b) { return a + b; } public int DoWork2(int a, int b) { return a - b; } } } 系统会自动添加App.config文件和相关配置节信息内容如下:

(完整版)快速搭建WCF服务程序

一、快速搭建WCF程序 1、ABC的概念 A:address:服务地址。访问网页时请求的地址 B:Binding: Client和Service的通道,例如访问web时,使用Http通道 WCF支持的通道有:BasicHttpBinding[WSHttpBinding],NetTcpBinding,netMSMQBinding. C:Contract:契约,包括定义的接口,参数,返回值,方法名 2、定义WCF项目 (1) 在新建项目中添加新建项,找到"WCF服务"这个模板。 (2) 步骤 Service:服务端 定义一个接口 PS:接口名可以随意改:例如在IFlyService 首先在接口名上面加一个ServiceContract特性 其次在方法名上面加一个OperationContract特性

●定义一个实现类 把接口中的方法改为String是想有返回值,方法名改为Fly,实现类中重写该方法。 ●定义配置文件 app.config中所有的定义都应该在System.serviceModel这个配置节点中。 ●承载WCF服务,一般可用IIS,Console,winform承载 Client:建立客户端连接Service (1)建立一个控制台应用程序 (2)然后添加服务引用,服务地址就是配置app.Config中host节点中的服务地址(可随意更改),注意一定要启动服务实例,才能访问服务 (3)下一步之后在Main方法启动代码如下: (4)然后启动实例可以看到控制台中打印出“Hello,World!”,启动成功。

注意:一定要以管理员身份打开VS。

WCF编程:WCF服务和客户端的建立

1.概念 Windows Communication Foundation(WCF)是由微软发展的一组数据通信的应用程序开发接口,可以翻译为Windows通讯接口。它是.NET框架的一部分,由 .NET Framework 3.0 开始引入。 WCF的终结点有三个要素组成,分别是地址(Address)、绑定(Binding)和契约(Contract),简记可写成Endpoint = ABC。 地址:地址决定了服务的位置,解决了服务寻址的问题。 绑定:绑定实现了通信的所有细节,包括网络传输、消息编码,以及其他为实现某种功能对消息进行的相应处理。绑定的类型包括BasicHttpBinding、WsHttpBinding、NetTcpBinding 等。 契约:契约是对服务操作的抽象,也是对消息交换模式以及消息结构的定义。 2.契约 WCF 的基本概念是以契约(Contract) 来定义双方沟通的协议,契约必须要以接口的方式来体现,而实际的服务代码必须要由这些合约接口派生并实现。契约分成了四种: 数据契约 (Data Contract),订定双方沟通时的数据格式。服务契约 (Service Contract),订定服务的定义。操作契约 (Operation Contract),订定服务提供的方法。消息契约 (Message Contract),订定在通信期间改写消息内容的规范。 如下图,解释了契约:

3.绑定 由于WCF 支持了HTTP,TCP,Named Pipe,MSMQ,Peer-To-Peer TCP 等协议,而HTTP 又分为基本HTTP 支持(BasicHttpBinding) 以及WS-HTTP 支持(WsHttpBinding),而TCP 亦支持NetTcpBinding,NetPeerTcpBinding 等通信方式,因此,双方必须要统一通信的协议,并且也要在编码以及格式上要有所一致。 基本绑定(BasicHttpBinding) 对应BasicHttpBinding类,能够将WCF服务公开为传统的ASMX Web服务,是以前就的程序能够使用现在的WCF服务。在实际开发中一个WCF服务可能会给不同的程序调用,如给Java的程序调用,给Flex的程序调用等,那么采用BasicHttpBinding最合适不过了 TCP绑定(NetTcpBinding)

不要在using语句中调用WCF服务

不要在using语句中调用WCF服务 如果你调用WCF服务时,像下面的代码这样在using语句中进行调用,需要注意一个问题。using (CnblogsWcfClient client = new CnblogsWcfClient()) { client.Say("Hello, https://www.doczj.com/doc/1218648008.html,!"); } 上面这段代码看上去没问题,CnblogsWcfClient是一个自动生成的WCF客户端代理,继承自System.ServiceModel.ClientBase。using语句结束时,会调用ClientBase实现的System.IDisposable.Dispose接口,实际就是调用ClientBase的Close()方法。用.NET Refector打开C:\Windows\https://www.doczj.com/doc/1218648008.html,\Framework\v4.0.30319\System.ServiceModel.dll,可以看到这样的代码,见下图: 不仅看上去没问题,似乎就是没问题。但是...问题就出在ClientBase.Close()上,Close()要关闭的是一个网络连接,如果这时网络连接出现问题,不能正常关闭会引发异常(ClientBase的Close方法就是这样设计的,引发异常,而不是强制关闭),问题就来了。本来我们使用using的目的就是不管出现什么状况,即使天塌下来,也给我关闭掉;结果,关是关了,却没有闭,天还是塌下来了。 也许我们可以用“不可抗拒力”回避这个问题,但程序员的天性是解决问题。代码中任何一个小问题都不能忽视,因为我们很难预料这个小问题会不会带来大问题。 那如何解决这个问题呢?MSDN中有答案(去MSDN看看),代码如下:CnblogsWcfClient client = new CnblogsWcfClient(); try

WCF简单实例

为了使读者对基于WCF的编程模型有一个直观的映像,我将带领读者一步一步地创建一个完整的WCF应用。本应用功能虽然简单,但它涵盖了一个完整WCF应用的基本结构。对那些对WCF不是很了解的读者来说,这个例子将带领你正式进入WCF的世界。 在这个例子中,我们将实现一个简单的计算服务(CalculatorService),提供基本的加、减、乘、除的运算。和传统的分布式通信框架一样,WCF本质上提供一个跨进程、跨机器以致跨网络的服务调用。在本例中,客户端和服务通过运行在相同的同一台机器上不同进程模拟,图1体现了客户端和服务端进程互相调用的关系。 图1 计算服务应用运行环境 WCF的服务不能孤立地存在,需要寄宿于一个运行着的进程中,我们把承载WCF服务的进程称为宿主,为服务指定宿主的过程称为服务寄宿(Service Hosting)。在我们的计算服务应用中,采用了两种服务寄宿方式:通过自我寄宿(Self-Hosting)的方式创建一个控制台应用作为服务的宿主(寄宿进程为Hos ting.exe);通过IIS寄宿方式将服务寄宿于IIS中(寄宿进程为IIS的工作进行W3wp.exe)。客户端通过另一个控制台应用模拟(进程为Client.exe)。接下来,我们就一步一步来构建这样的一个WCF应用。 步骤一:构建整个解决方案 通过VS 2008创建一个空白的解决方案,添加如下四个项目。项目的类型、承载的功能和相互引用关系如下,整个项目在VS下的结构如图2所示。 Contracts:一个类库项目,定义服务契约(Service Contract),引用System.ServiceMode程序集(W CF框架的绝大部分实现和API定义在该程序集中);

WCF服务编程

免费试读章节 (非印刷免费在线版) 如果你喜欢本书,请购买印刷版以支持作者和InfoQ中文站 向O’Reily和机械工业出版社致谢 本图书节选由InfoQ中文站免费发放,如果你从其他渠道获取此摘选,请注册InfoQ 中文站以支持作者和出版商 本摘选主页为 https://www.doczj.com/doc/1218648008.html,/cn/articles/programming-wcf-services

序 言 对于分布式系统,或者说业界不断提及的互联系统的设计与构建,我与本书作者Juval Lowy可谓志同道合。我们经历了相似的技术历程,虽然我们效力于不同的公司,负责不同的项目,工作在不同的地方,但我们却有着共同的目标。 20世纪90年代早期,我们开始了对一种新技术理念的探索,即实现计算机之间的通信与交互。这种被称为分布式系统应用程序的平台技术也逐渐为世人所了解。随着工作站与服务器硬件的逐渐普及,经济因素不再成为制约发展的瓶颈,构建不依赖于单事务网络中心的大型系统就成为了技术热点。对于大范围的数据交换系统而言,同样如此。在过去,我的电话公司如果要求每秒钟传递超过1200位的数据几乎是不可能的,而在如今看来连这都达不到简直不可思议。在同样的线路上,今天的传输速度已经达到了6Mbit/s。这真是一个激动人心的时代啊。 随着分布式计算技术的逐渐成熟,在90年代早期分属两大阵营的大型分布式系统技术渐露峥嵘,即数字设备公司(最终被康柏兼并,并入惠普)主导的DCE技术,以及OMG 组织(主要由IBM支持)倡导的CORBA技术。然而在1996~1997期间,所有这些杰出的工程学成果却突然停滞不前。因为此时是互联网的世界,整个世界都疯迷于HTML、HTTP、风险投资以及IPO(Initial Public Offerings,首次公开募股)。整个行业花费了整整10年的时间才逐渐从泡沫经济带来的崩溃中恢复过来。不仅是经济的复苏,技术的发展也重新走回正轨。随之获益的是分布式系统技术由此打破了过去由两大阵营各占半壁江山的局面,多达数十种新的分布式技术如雨后春笋一般展现在人们眼前,使我们拥有了更多的抉择权。 直到2007年,整个行业仍然在为分布式系统的正确编码方式争论不休。Sun公司或者BEA力主Java;而我在微软的同事(包括我)则坚定地主张C#或者Visual Basic才是最佳的实现方式。无论是Sun、BEA、IBM还是微软,都希望机器之间的通信标准能够达成一致。试想昔日的DCE与CORBA之争,正是因为达成了一致的标准规范才为如今的SOAP 1.1奠定了基础,从而开创了分布式技术的盛大场面。 自从SOAP 1.1作为技术说明(Technical Note)被提交给W3C,到现在已有超过6年的历史。期间,多家行业合作商共同开发与协定了众多基于SOAP的规范,从包括寻址以及众多安全选项的基础规范,到诸如原子事务协作的企业协议。我在微软的团队,仍然非正式地称呼我们的产品为“Indigo”,它代表了整个开发与协商过程中耗费的所有心血。如果没有IBM、微软以及其他合作伙伴对创建通用标准集的大力支持,在竞争如此激烈的企业领域几乎不可能存在开放标准的框架,更不可能具有支持多个开发商以及各种平台的多种实现。 诚然,WCF的实现超出了预计需要花费的时间。标准的协定耗费了大量时间,毕竟我们不能只顾着发布自己的软件(Windows Communication Foundation, WCF),而不考虑它与我们的行业合作伙伴以及竞争者之间的互操作性。设计同样如此,对于那些具有分布式系统开发经验的客户而言,他们花费了大量时间学习以及掌握了我们之前提供的分布式系统技术,包括https://www.doczj.com/doc/1218648008.html,服务、Web服务增强(WSE)、.NET Remoting、消息传输/MSMQ以及企业服务/COM+,我们在发布软件的同时必须考虑这些客户。

相关主题
文本预览
相关文档 最新文档