65.9K
CodeProject 正在变化。 阅读更多。
Home

Windows Communication Foundation FAQ 快速入门: 第一部分

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.82/5 (119投票s)

2008年9月19日

CPOL

21分钟阅读

viewsIcon

335596

Windows Communication Foundation 常见问题快速入门:第 1 部分。

更新了WCF 第 2 部分、WPF、WWF、WCF 跟踪常见问题、在 WCF BasicHttpBinding 上启用 Windows 身份验证的 8 个步骤、BasicHttpBinding 和 WsHttpBinding 之间的区别、WCF 常见问题第 3 部分 – 10 个安全相关常见问题、SilverLight 常见问题第 1 部分和第 2 部分、使用 LINQ to SQL 实现一对多和一对一关系的链接。

目录

这个10分钟的小视频解释了如何在 WCF 服务中使用 SSL 实现传输安全。

引言

在本节中,我们将快速浏览 WCF 的常见问题。我相信阅读完本节后,您将对 WCF 的基础知识有很好的了解。

祝您阅读愉快……

  • 点击这里查看 Windows Communication Framework (WCF) - 第 2 部分
  • 点击这里查看 Windows Presentation Foundation (WPF)
  • 点击这里查看 Windows Workflow Foundation (WWF)
  • 点击这里查看 Windows Communication Framework (WCF) 跟踪常见问题
  • 点击这里查看在 WCF BasicHttpBinding 上启用 Windows 身份验证的 8 个步骤
  • 点击这里查看 BasicHttpBinding 和 WsHttpBinding 之间的区别
  • 点击这里查看 WCF 常见问题第 3 部分 – 10 个安全相关常见问题
  • 点击这里查看 21 个重要的 SilverLight 常见问题 - 第 1 部分
  • 点击这里查看(动画和转换)SilverLight 常见问题 - 第 2 部分
  • 点击这里查看使用 LINQ to SQL 实现一对多和一对一关系

什么是 .NET 3.0?

用一个简单的等式来表示:.NET 3.0 = .NET 2.0 + Windows Communication Foundation + Windows Presentation Foundation + Windows Workflow Foundation + Windows Card Space。

什么是 Windows Card Space?

它以前的代号是 Info Card。这是微软的一个框架,可以安全地存储用户的数字身份,并提供一个统一的界面来为特定交易(如登录网站)选择身份。Windows Card Space 是微软创建身份元系统(一个统一、安全且可互操作的互联网身份层)的核心部分。

什么是 WCF?

首先我们给出一个简短的回答:“WCF(其代号为 Indigo)是 .NET Framework 通信技术的统一体”。WCF 是一个统一技术,它整合了以下技术:

  • NET 远程处理
  • MSMQ
  • Web 服务
  • COM+

下图以图示方式描绘了 WCF 的基础知识。

图 1:WCF 组件

SOA(面向服务的架构)的重要原则是什么?

WCF 基于 SOA。所有大公司都在 SOA 上下了大赌注。那么微软怎能落后呢?为了轻松实现 SOA 架构,您需要使用 WCF。SOA 基于四个重要概念:

边界清晰明确

在 SOA 中,一切都是形式化的。消费服务的客户端不需要知道服务的实现方式。如果您看一些旧的通信方法,比如 DCOM,服务器端的任何更改都必须导致客户端的更改。服务器和客户端的实现是如此紧密地绑定在一起,以至于需要在所有地方进行更改。在 SOA 中,规则是如果您进行增强,您不需要在客户端进行任何更改。基于 SOA 的应用程序只理解存在终结点、协定和绑定。

注意:简单解释一下终结点和协定。任何 SOA 服务都通过终结点公开。终结点定义了三个重要方面:什么(What)、哪里(Where)和如何(How)。我们将在接下来的部分中了解更多细节。

服务是不断演进的

变化是自然法则,服务也会不断演进。在 SOA 中,服务可以进行版本控制,并且您可以将这些服务托管在新的终结点上。例如,您有一个名为“Search Tickets (Ticket Number)”的服务,它根据票号提供详细信息,并暴露在终结点“ep1”上。明天,您希望通过提供一个额外的选项,即允许按乘客姓名搜索,来使您的“Search Tickets”服务更有用。因此,您只需声明一个新的终结点“ep2”,其服务为“Search Tickets (Ticket Number, Passenger Name)”。正在使用终结点 ep1 的客户端继续工作,而在另一端,我们通过添加新的终结点 ep2 来演进我们的服务。

服务只共享模式和协定

服务使用模式(Schemas)来表示数据,使用协定(contracts)来理解行为。它们不使用依赖于语言的类型或类来理解数据和行为。XML 用于定义模式和协定。因此,环境之间没有强耦合。

服务兼容性是基于策略的

策略描述了系统的能力。根据策略,服务可以降级以匹配客户端的服务。例如,您的服务需要为两种类型的客户端托管,一种使用远程处理(Remoting)作为通信方法,另一种客户端使用 DCOM。一个理想的 SOA 服务可以根据它们的通信策略为两者提供服务。

注意:许多人认为 Web 服务是 SOA 的基础。这个答案有 50% 是正确的。Web 服务所缺乏的是基于策略的服务兼容性。如果您托管一个 Web 服务,它只能通过 HTTP 通信通道和 SOAP 消息提供服务。任何其他类型的客户端尝试通信时,它都不会自我降级。这正是 WCF 所提供的。您可以以一种或多种模式托管服务。例如,您可以使用远程处理和 ASMX 来托管 WCF 服务。

什么是终结点、协定、地址和绑定?

以上术语是 SOA 赖以存在的核心。每个服务都必须公开一个或多个终结点,客户端可以通过这些终结点使用该服务。一个终结点由三个重要部分组成:哪里(where)、什么(what)和如何(how)。

协定(什么)

协定是两方或多方之间的协议。它定义了客户端应如何与您的服务通信的协议。技术上讲,它描述了一个方法的参数和返回值。

地址(哪里)

地址指示了我们可以在哪里找到这个服务。地址是一个指向服务位置的 URL。

绑定(如何)

绑定决定了如何访问此终结点。它决定了通信的完成方式。例如,您公开您的服务,该服务可以通过 SOAP over HTTP 或 BINARY over TCP 访问。因此,对于这些通信媒介中的每一个,都将创建两个绑定。下图显示了一个终结点的三个主要组件。您可以看到股票行情服务是服务类,它有一个托管在 www.soa.com 上的终结点,支持 HTTP 和 TCP 绑定,并使用 Stock Ticker 接口类型。

图 2:终结点架构

注意:您也可以通过 ABC 来记住终结点,其中 A 代表地址(Address),B 代表绑定(bindings),C 代表协定(Contract)。

WCF 遵循哪些规范?

WCF 支持由 WS-* 规范定义的规范。WS-* 规范由微软、IBM、SUN 和许多其他大公司共同定义,以便它们可以通过一个通用协议来公开其服务。WCF 支持所有已定义的规范,现在我们将逐一学习它们。

  • 消息传递 (WS-Addressing):SOAP 是 Web 服务的基本协议。WS-Addressing 为 SOAP 头定义了一些额外的补充,使得 SOAP 独立于底层传输协议。消息传输的一个优点是 MTOM,也称为消息传输优化机制。它们使用 XML 优化封装(XOP)来优化 XML 二进制格式的 SOAP 消息的传输格式。由于数据将以二进制和优化的格式发送,这将给我们带来巨大的性能提升。
  • 安全 (WS-Security, WS-Trust, and WS-Secure Conversation):这三个 WS- 规范定义了服务的身份验证、安全性、数据完整性和隐私功能。
  • 可靠性 (WS-Reliable Messaging):当我们需要 SOAP 消息多次来回传递时,此规范可确保端到端的通信。
  • 事务 (WS-Coordination and WS-Atomic Transaction):这两个规范启用了使用 SOAP 消息的事务处理。
  • 元数据 (WS-Policy and WS-Metadata exchange):WSDL 是 WS-Metadata Exchange 协议的一种实现。WS-Policy 定义了服务更动态的特性,这些特性无法用 WSDL 来表达。我们强调 WS-* 规范,因为这是一个服务必须遵循的规范,以便与其他语言兼容。由于 WCF 遵循 WS-* 规范,其他语言如 Java、C++ 也可以利用用 C# 或 VB.NET 编写的消息传递、安全性、可靠性和事务等功能。这是 WCF 在将上述功能与其他语言集成方面取得的最大成就。

注意:在面试中,面试官期望您知道 WCF 支持哪些 WS-* 规范,以及它在与其他语言交互方面的优势。

WCF 的主要组件有哪些?

我们需要在 WCF 中定义三个主要组件:

  • 服务类
  • 托管环境
  • 终结点

什么是服务协定、操作协定和数据协定?

在本例中,我们将创建一个简单的服务,用于显示整个产品组的总成本。简单来说,该服务将接受三个参数:每个产品的成本、产品数量和产品名称。作为回报,服务将通过将产品数量与每个产品的成本相乘来返回所有产品的总成本。随着我们对这个解释的深入,我们将尝试理解上述问题中提到的所有术语。首先,您需要创建一个 WinFx 服务项目。您可以在下图中看到我们选择了 WinFx 项目。

图 3:创建新的 WinFX 服务类

在这个项目中,我们添加一个新类并将其命名为 *serviceGetCost.cs*。这个类将包含我们的核心实现,也是所有操作发生的类。服务类必须向外部客户端公开。我们需要使用 ServiceContract 属性将其标记为服务类。ServiceContract 属性定义了哪个应用程序接口将被公开为服务。您可以在下面的代码片段中看到我们创建了一个接口并将其标记为 ServiceContract。使用接口并非必须,您也可以使用一个简单的类并将其标记为服务,但接口代表一个协定并且没有实现。简而言之,它们处于一个非常高的抽象层次。因此,作为一种好的设计实践,使用接口来表示服务协定更有意义。

接下来要注意的是 OperationContract 属性。OperationContract 规定了哪些方法应该通过此服务向外部客户端公开。它定义了单个的交换或请求和回复。在当前示例中,我们定义了 `GetTotalCost` 方法,最终客户端将使用该方法获取总成本结果。代码片段中需要注意的下一件事是 DataContract 属性。在前两个步骤中,我们通过使用 ServiceContract 将一个类公开为服务,并通过使用 OperationContract 公开了方法。每个操作肯定会进行某种数据传输。DataContract 属性定义了在客户端和服务之间交换哪种类型的复杂数据。它们决定了哪些参数需要被序列化。当您使用像 int、bool 等简单数据类型时,不必标记 DataContract 属性。因为您总能在客户端找到匹配的类型。但是,对于如下面代码片段所示的复杂结构,您将需要定义一个数据协定。请记住,数据协定定义了此数据在传输过程中的传递方式。简而言之,DataContract 属性定义了数据在传输中如何被序列化。在下面的示例中,我们已将 product data 结构标记为要序列化。

图 4:服务类

由于数据协定完全与序列化有关,您需要导入 `System.Runtime.Serialization` 命名空间。在下一步中,我们实现 `GetTotalCost` 函数。它只返回一个简单的字符串,其中包含产品名称和所有产品的总成本。一旦我们的服务类完成,就该托管这个服务了。托管 WCF 服务有多种方式,我们将在下一个问题中探讨。对于当前示例,我们将在其自己的进程中进行托管。

图 5:托管服务

托管 WCF 服务需要两样东西:一个是配置文件,第二个是启动时的托管代码。因为我们是在其自己的应用程序进程中托管此服务,所以这需要是一个 Windows 应用程序。所以首先让我们看看需要在 *App.config* 文件中做哪些配置。

在上图中,所有内容都很清晰,但让我们来理解 *App.config* 文件中定义的所有部分。在配置部分,我们需要添加一个新的部分 ``。`` 最重要的部分是 endpoint 标签。如前所述,End 提供了三个重要的答案:Where(哪里)、What(什么)和 How(如何)。简而言之,服务在哪里,服务的协定是什么,以及我们如何与服务通信。在上面的代码片段中,我们只定义了协定,即“什么”,以及绑定,即“如何”。“哪里”是在应用程序入口点 `static void main ()` 中定义的。因此,contract 属性定义了接口,而 binding 则表示最终客户端可以使用 HTTP 协议进行通信。在 `static void Main` 方法中,我们创建了一个 ServiceHost 类的对象,并使用 `Open` 方法来托管服务。我们使用了 URI 对象来定义服务将被托管的地址。

图 6:服务已启动

如果您编译该项目,您将看到如上图所示的内容。这表示服务已启动并正在运行,准备为任何 WCF 客户端提供服务。现在是时候开发将使用此 WCF 服务的消费者了。微软提供了一个不错的自动化工具来生成客户端。下图描绘了各个步骤:

图 7:svcutil 正在运行

转到 Windows SDK 的命令提示符并运行以下命令:

Svcutil <Service hosted URI>

在上述命令中,*<Service Hosted URI>* 是服务托管的 URI。一旦您对该 URI 运行该命令,它将生成两个文件:配置文件和代理类。您可以在上图中看到生成了两个文件:*serviceGetCost.cs* 和 *output.config*。借助这两个文件,我们将创建我们的客户端。

图 8:客户端代码详解

您可以在上图中看到我们已经创建了 WFCClientGetCost 项目。在该项目中,我们已将 *output.config* 和 *serviceGetCost.cs* 添加到客户端项目中。我们已将 *output.config* 重命名为 *app.config*。完成所有操作后,就该编写客户端代码了,该代码将调用代理,而代理又将调用托管的服务。在上图中,您也可以看到客户端代码。这是一个简单的代码:我们首先创建数据结构的对象并设置值。然后我们创建服务对象并调用 `GetTotalCost` 函数。如果一切都已编译并且您运行了服务器和客户端,您应该会得到如下所示的输出。

图 9:WCF 服务输出

托管 WCF 服务有哪些不同方式?

托管 WCF 服务主要有三种方式:

  • 在其自己的应用程序域中自托管服务。这一点我们已经在第一部分中介绍过了。当您创建 ServiceHost 类的对象时,服务就存在了;当您调用 ServiceHost 类的 `Close` 方法时,服务就关闭了。
  • 在 IIS 服务器提供的应用程序域或进程中托管。
  • 在 WAS(Windows 激活服务)服务器提供的应用程序域和进程中托管。

我们如何在 IIS 中托管 WCF 服务?

注意:了解如何在 IIS 中托管 WCF 的最佳方法是做一个小示例。因此,我们将托管与上一节中自托管的相同的 GetCost 示例。

首先,您需要创建用于公开服务类的 SVC 文件。SVC 文件包含指向该类的指针。从下图中您可以看到,class 属性指向的类,其接口由 *service.svc.cs* 文件公开。另外,请注意实际的接口在 *service.svc.cs* 文件中。下图同时显示了 *service.svc* 文件(其中包含指向服务类的 class 属性)和位于 *service.svc.cs* 文件中的接口。我们采用了与前一个问题中自托管相同的示例。

图 10:SVC 文件和其后台代码

我们还需要为接口提供一个实现。因此,我们创建了一个名为 `ServiceGetCost` 的类,其中包含了实际的实现。下图详细显示了这一点。在下图中,您还可以看到解决方案文件。

图 11:Service.svc.cs 的实现

我们还需要在 *web.config* 文件中指定服务类型和终结点。另请注意,我们已经指定了 HTTP 绑定,因为我们将在 IIS 上托管该服务。

图 12:用于在 IIS 上托管服务的 Web.config 文件

现在我们已经完成了编码部分,我们需要在 IIS 中创建虚拟目录。在下图的步骤 1 和步骤 2 中,我们可以看到如何在 IIS 中创建虚拟目录。在创建虚拟目录时需要注意的一件重要事情是,将访问权限设置为*执行*。

图 13:IIS 配置

在第三步中,我们将把网站发布到我们的虚拟目录。请注意第四步,我们复制了 *svc* 文件,以便可以请求该服务。注意:ASP.NET 的编译在 ASP.NET 2.0 中发生了变化。在 2.0 中,没有解决方案文件的概念。所以如果你想要一个完全编译的 DLL,你需要将项目发布到虚拟目录。一旦你托管了 SVC 文件,你可以通过请求 *service.svc* 文件来测试它。如果一切正常,你会得到如下图所示的结果。

图 14:IIS WCF 客户端

使用 *Svcutil.exe*,您将需要生成代理类和配置文件。代理和配置将与我们为自托管所做的相同。一个重要的变化是地址。配置文件 URL 现在指向托管在 IIS 上的 *service.svc*。您可以运行我们为自托管创建的相同客户端。您唯一需要做的更改是更改终结点地址。

图 15:IIS 上的 WCF 客户端输出

您应该得到与我们为自托管收到的相同的输出。

与自托管相比,在 IIS 中托管 WCF 服务有哪些优势?

使用 IIS 而不是自托管主要有两个优点:

自动激活

IIS 提供自动激活功能,这意味着服务不必预先运行。当服务收到任何消息时,它才会启动并完成请求。但在自托管的情况下,服务必须始终处于运行状态。

进程回收

如果 IIS 发现某个服务不健康,即存在内存泄漏等问题,IIS 会回收该进程。让我们尝试理解 IIS 进程中的回收是什么。对于每个浏览器实例,都会生成一个工作进程来处理请求。当浏览器断开连接时,工作进程停止,您将丢失所有信息。IIS 也会重新启动工作进程。默认情况下,工作进程大约在 120 分钟内被回收。那么 IIS 为什么要回收呢?通过重新启动工作进程,可以确保任何不良代码或内存泄漏不会对整个系统造成问题。在自托管的情况下,上述两个功能都需要您自己编码。工作量很大,对吧?这就是为什么除非您真的在做一些自定义的事情,否则 IIS 是托管服务的最佳选择。下图显示了回收选项在 IIS 中的位置。您需要点击 DefaultAppool,然后点击属性。

图 16:IIS 回收选项

WCF 和 Web 服务之间有什么区别?

Web 服务只能通过 HTTP 调用。而服务或 WCF 组件可以被任何协议和任何传输类型调用。其次,Web 服务不灵活。然而,服务是灵活的。如果您创建了一个新版本的服务,您只需要公开一个新的终结点即可。因此,服务是敏捷的,这在当前的商业趋势下是一种非常实用的方法。

WCF 支持哪些不同的绑定?

WCF 包含预定义的绑定。它们涵盖了日常应用中广泛需要的大部分绑定。但是,万一您发现需要定义一些自定义的东西,WCF 并不会阻止您。那么让我们来了解一下每种绑定都提供了什么:

注意:MTOM 已在本章前面的一个问题中讨论过。

注意:进程间控制(IPC)协议用于在两个应用程序之间交换信息,这两个应用程序可能运行在网络中的不同计算机上。命名管道和 TCP 的区别在于,命名管道在进程内通信方面性能更好。但当涉及到跨网络通信时,TCP 是最佳选择。所以如果您使用 WCF 与某个进程通信,从性能角度来看,这是最佳选择。与 TCP/IP 相比,当流量很大时,命名管道的性能不佳。

  • BasicHttpBinding:当我们需要使用 SOAP over HTTP 时,使用此绑定。此绑定也可以配置为使用 HTTPS。它还可以配置为以纯文本或优化形式(如 MTOM)发送数据。
  • WsHttpBinding:它与 BasicHttpBinding 相同。简而言之,它使用 SOAP over HTTP。但它还支持可靠消息传输、安全性和事务。WS-Reliable Messaging 支持可靠消息,WS-Security 支持安全性,WS-Atomic Transaction 支持事务。
  • NetTcpBinding:此绑定直接通过 TCP 发送二进制编码的 SOAP,包括对可靠消息传输、安全性和事务的支持。NetTcpBinding 的最大缺点是服务器和客户端都必须使用 .NET 语言编写。
  • NetNamedPipesBinding:此绑定通过命名管道发送二进制编码的 SOAP。此绑定仅适用于同一台基于 Windows 的机器上进程之间的 WCF 到 WCF 通信。
  • NetMsmqBinding:此绑定通过 MSMQ 发送二进制编码的 SOAP。此绑定只能用于 WCF 到 WCF 的通信。

什么是单向操作?

将 IsOneWay 设置为 true 可确保客户端不必等待响应。因此,被标记为 `IsOneWay` 为 `true` 的方法应始终返回 `void`。在这种情况下,调用者不会得到任何返回,因此它被称为单向通信。为了理解 WCF 中的单向实现,让我们通过一个示例代码来详细了解。注意:您可以在“*WCFIsOneWay*”文件夹中找到相关代码。

图 17:单向操作示例

以上是代码片段,实际描述了单向操作在 WCF 中是如何工作的。上述代码片段已编号。下面是根据图中标记的数字进行的解释:

  1. 这是服务器服务的代码片段。我们创建了一个名为 `doHugeTask` 的方法。`DoHugeTask` 使方法休眠 5000 毫秒,然后显示任务完成的时间。
  2. 此代码片段是客户端的。它创建了 `serviceIsOneWay` 的代理对象,并调用了 `doHugeTask` 方法。调用 `doHugeTask` 后,客户端继续执行。为了证明这一点,我们显示了方法调用完成的时间。
  3. 此屏幕截图显示了服务器和客户端的输出。顶部窗口显示服务器输出,底部窗口显示客户端输出。

注意:您可以在 *WCFIsOneWay* 文件夹中找到代码。要生成代理,您必须遵循前面部分中显示的相同步骤。

首先运行服务器程序,即 ServiceIsOneWay,然后再运行客户端。您会看到客户端运行 `doHugeTask` 后继续执行。因此,客户端的完成时间比服务器的要短。另外需要理解的一点是,单向操作不会返回任何完成通知。因此,这就像是“发后不理”。

如需进一步阅读,请观看以下面试准备视频和分步视频系列。

© . All rights reserved.