4

我有一个 Silverlight 客户端在 IIS Web 服务器上调用 WCF 服务。它对调用使用默认的 basicHttpBinding 设置。我的客户端代码具有使用“更新服务参考”菜单选项时生成的常用 Visual Studio 生成代理。

使用该代理对服务的每次调用是否都使用相同的连接?还是每次拨打电话时都会建立连接,然后在收到回复后将其关闭?由于客户端实际上是通过 HTTP 进行 SOAP 调用,我只是假设每个服务请求都创建了一个新连接,但我想检查是否是这种情况?

(我需要知道,因为如果它每次都创建一个新连接,那么每个请求都可能在不同的服务器上结束,因为有几台服务器正在负载平衡。它在代理期间使用单个连接,那么我可以假设他们所有最终都在同一台机器上,因此缓存状态信息以获得更好的性能。)

4

1 回答 1

6

您必须区分连接和会话。Connection 允许您调用服务器。会话允许您在来自同一客户端的后续请求中维护状态。例如,应用程序会话允许使用服务器端缓存。首先 BasicHttpBinding 不支持会话。

HTTP 1.1 规范描述了每个连接都应该以持久的方式打开。当您向新服务器调用第一个 HTTP 请求时,将建立一个持久连接并保持打开状态以供后续调用同一服务器。如果您不再次调用服务器,它会在超时后关闭。持久连接的打开和关闭在内部处理,对开发人员完全透明。

所有浏览器和 HTTP API 都使用持久连接,包括 .NET HttpWebRequest 和所有基于 HTTP 的绑定。您可以通过创建自定义绑定并将 HTTP 传输通道和属性KeepAliveEnabled设置为 false 来要求为每个请求/响应创建和关闭新连接。它将增加额外的开销,因为将为每个请求/响应建立新的 TCP 连接。建立 TCP 连接是一项耗时的操作。

持久 HTTP 连接与 WCF 应用程序会话无关。默认情况下,WCF 会话在单个服务代理实例和单个服务实例之间处理。来自同一代理实例的所有后续调用都由同一服务实例(PerSession 实例化)处理。WCF 应用程序会话建立在任何其他会话之上——连接、安全、可靠。BasicHttpBinding 不支持任何这些会话类型,因此它不能使用 WCF 应用程序会话(和 PerSession 实例化)。默认情况下,BasicHttpBinding 上公开的每个服务请求都由新服务实例(PerCall 实例化)处理。

根据 HTTP 规范,客户端应该只能打开两个到同一服务器的并发持久 HTTP 连接。在同一时间段内,从同一客户端机器调用同一服务器的所有服务代理共享持久 HTTP 连接。此外,如果调用之间经过很长时间,单个代理实例可以从许多不同的连接调用服务。这就是为什么持久 HTTP 连接不能用作连接会话的原因。HTTP 不是面向连接的——它只允许出于性能原因重用连接。

WCF 中持久 HTTP 连接的不活动超时为 100 秒。我通过测量 Procmon 发现了这个超时。关于将此超时设置为不同的值,我有未回答的问题。

当您使用负载平衡时,您也不能依赖连接。在客户端和负载均衡器之间打开持久 HTTP 连接。但是选择处理服务器是负载平衡算法的责任。在 BasicHttpBinding 的情况下,它可以是简单的循环,因为处理服务器不会使用任何类型的会话。在面向会话的绑定的情况下,您必须使用一些具有会话亲和性(粘性会话)的算法,它将来自同一会话的所有请求转发到同一服务器,以便同一服务实例可以处理它们。但BasicHttpBinding 并非如此。

于 2010-12-26T18:54:25.560 回答