Windows 通信基础(Windows Communication Foundation)

来源:互联网 发布:java十大低级错误 编辑:程序博客网 时间:2024/05/18 03:33

Windows 通信基础(Windows Communication Foundation

 

Windows 通信框架(Windows Communication FrameworkWCF)的目标是提供创建分布式应用程序的统一模型,其概念是创建一个服务,有点类似于网站服务,包含想要公开的功能,然后,以各种不同方法公开这个服务。例如,网站服务总是传递 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

0 0
原创粉丝点击