您的位置:首页 > 其它

Windows 通信基础(Windows Communication Foundation)

2014-05-26 16:05 357 查看
Windows 通信基础(Windows Communication Foundation)

Windows 通信框架(Windows Communication Framework,WCF)的目标是提供创建分布式应用程序的统一模型,其概念是创建一个服务,有点类似于网站服务,包含想要公开的功能,然后,以各种不同方法公开这个服务。例如,网站服务总是传递
XML 消息,但是,可以把 WCF 服务配置成既能传递 XML
消息,还能传递二进制数据;另外,WFC 服务可以托管在任何进程中,不仅仅是托管在网站服务器上。这就是说,我们可以创建桌面应用程序来监听入站消息,而不需要在桌面上没有安装网站服务器。

注意

WCF 是 .NET
框架 3 的一部分,提供了一组编程接口,随 Windows Vista
同时发行,且已经安装在操作系统中;也可以从 http://www.microsoft.com 上下载,安装在 Windows XP和 Windows
服务器 2003 上(http://blogs.msdn.com/b/dotnet/p/dotnet_sdks.aspx,原文提供的地址好像不能下载了;.NET
的安装也越来越复杂了)。WCF 使用的协议是基于一组扩展网站服务的规范,有时简称为 WS-*
协议,因为每一个协议通常都以 WS- 前缀命名,比如,WS-Security
和 WS-Reliability;这些协议有的已经标准化,有的即将标准化。为了开发 WCF,需要从 http://is.gd/4US4W 下载 .NET 框架 3 SDK。

在第一个示例(见清单 11-9)中,我们将构建一个简单的 WCF
服务,托管在网站服务器中,看起来更像一个简单的网站服务;然后,再改进这个服务,以展示 WCF
的有趣功能。为了创建在网站服务器上托管的 WCF 服务,与在“创建网站服务”一节中讨论的步骤相同,不同的是,不能托管在运行 Linux
的 Apache 上,因为 WCF
依赖于 Windows 的一些特定功能。

清单11-9 创建简单的 WCF
服务

namespace Strangelights.Services

open System.ServiceModel

// the service contract

[<ServiceContract

(Namespace =

"http://strangelights.com/FSharp/Foundations/WCFServices")>]

type IGreetingService =

[<OperationContract>]

abstract Greet : name:string -> string

// the service implementation

type GreetingService() =

interface IGreetingService with

member x.Greet(name) = "Hello: " + name

这个服务的定义分成两个部分,一个是描述服务契约的接口,另一个是契约的实现。所有 WCF
服务都以这种方法定义。这个接口名为 IGreetingService,公开一个函数 Greet。要使 WCF
契约有用,还必须用 System.ServiceModel.ServiceContractAttribute
标记接口,它应该包含服务的命名空间;在服务接口内部,打算公开的每一个函数都要用 OperationContractAttribute
去标记。每一个参数都有名字[ ,这一点很重要 ];在 F#
中,创建接口的参数可能没有名字,而是由它们的类型定义。作为 WCF 契约的接口,如果其函数没有参数,是能够编译的,但是,当你调用这个服务时会报错,因为在 WCF
框架中,这个参数名是用于(通过反射 reflection)创建在网络上发送的数据。GreetingService
类实现了契约,简单地提供一个问候语,把传递的名字加到“hello:”的后面。

为了把服务集成到网站服务器,需要创建 .svc
文件,它的作用与网站服务的 .asmx 文件相似,告诉网站服务器应该用什么类型来处理这个服务请求。在下面的示例中可以看到这个服务一致的 .svc
文件;注意,我们在这个示例中看到的就是完整的文件,这种文件通常只有一行。在 .svc
文件中最重要的特性是 Service,它告诉网站服务器应该使用哪一种类型:

<% @ServiceHost Debug="true" Service="Strangelights.Services.GreetingService" %>

最后,必须配置服务。因为 WCF
可以选择协议,所以要使用配置文件告诉它使用哪一个。清单 11-10 中的配置文件显示了能够用来配置服务的配置文件。Service
元素定义两个端点,这些协议是客户端用来和服务对话的。其中一个端点是标准的网站服务 HTTP
绑定,另一个是元数据交换绑定;它允许服务公开有关它自身的元数据,将告诉任何潜在的客户端应该如何与服务对话。当创建客户端代理时,将使用这个端点。

清单 11-10 WCF
服务的配置文件

<configuration xmlns="http://schemas.microsoft.com/.NetConfiguration/v2.0">

<system.serviceModel>

<services>

<service

name="Strangelights.Services.GreetingService"

behaviorConfiguration="MyServiceTypeBehaviors">

<endpoint

contract="Strangelights.Services.IGreetingService"

binding="wsHttpBinding"/>

<endpoint

contract="Strangelights.Services.IGreetingService"

binding="mexHttpBinding" address="mex"/>

</service>

</services>

<behaviors>

<serviceBehaviors>

<behavior name="MyServiceTypeBehaviors" >

<serviceDebug includeExceptionDetailInFaults="true" />

<serviceMetadata httpGetEnabled="true" />

</behavior>

</serviceBehaviors>

</behaviors>

</system.serviceModel>

<system.web>

<compilation debug="true"/>

</system.web>

</configuration>

为了创建这个服务的客户端,需要使用工具 SvcUtil.exe,它的目的与我们在“创建网站服务”一节讨论过的 wsdl.exe
工具相似。使用 SvcUtil.exe 创建服务的代理,用下面的命令行,适当地改变一下 URL:

svcutil.exe http://localhost:1033/WCFService/Service.svc?wsdl
这将生成一个 C#
代理文件,然后,可以把它编译成一个 .NET 程序集在 F#
中使用;它还生成一个 .config 文件,可以用于配置任何客户端的应用程序。

使用代理就变得非常简单了,添加了对这个代理的 .dll
文件的引用以后,只要创建代理的实例,就可以用适当的参数调用它的 Greet
方法了。清单 11-11 展示了代理的一个示例;因为调用代理的 Dispose
方法很重要,所以,实例化代理时,使用了 use 绑定[
原文忘记修改了,还是第一版的内容。 ]。

清单 11-11 调用 WCF
服务

open System

let main() =

use client = new GreetingServiceClient()

while true do

printfn "%s" (client.Greet("Rob"))

Console.ReadLine() |> ignore

use client = new GreetingServiceClient()

printfn "%s" (client.Greet("Rob"))

Console.ReadLine() |> ignore

do main()

清单 11-12 是一个产生的配置文件的示例,已经删除了一些特定的内容,以保证示例运行得更加顺利。安全设置已经删除,因为如果运行在一台脱离域控制器的计算机上(在开发环境中很常见的!),可能会引起示例的失败。另外,产生的两个端点中有一个也已经删除,因此,在代码中就不需要指定端点了。

清单 11-12 调用 WCF
服务的配置文件

<configuration>

<system.serviceModel>

<bindings>

<wsHttpBinding>

<binding name="WSHttpBinding_IGreetingService"

closeTimeout="00:01:00" openTimeout="00:01:00"

receiveTimeout="00:10:00" sendTimeout="00:01:00"

bypassProxyOnLocal="false" transactionFlow="false"

hostNameComparisonMode="StrongWildcard"

maxBufferPoolSize="524288"

maxReceivedMessageSize="65536" messageEncoding="Text"

textEncoding="utf-8" useDefaultWebProxy="true"

allowCookies="false">

<readerQuotas maxDepth="32"

maxStringContentLength="8192"

maxArrayLength="16384"

maxBytesPerRead="4096"

maxNameTableCharCount="16384" />

<reliableSession ordered="true"

inactivityTimeout="00:10:00"

enabled="false" />

</binding>

</wsHttpBinding>

</bindings>

<client>

<endpoint address="http://localhost:8080/service"

binding="wsHttpBinding"

bindingConfiguration="WSHttpBinding_IGreetingService"

contract="IGreetingService"

name="WSHttpBinding_IGreetingService">

</endpoint>

</client>

</system.serviceModel>

</configuration>

运行清单 11-11
产生的结果如下:

Hello: Rob
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: