2

我正在使用 VSTS2008 + C# + .Net 3.5 开发托管在 IIS 中的 WCF 服务。然后我使用 VSTS 2008 中的添加服务引用功能自动生成客户端代理代码。

我的问题是,假设我创建了一个客户端代理实例,然后使用这个特定的实例来调用 WCF 服务在服务器端公开的各种方法。那么,每次我进行方法调用时,它会建立一个新的连接吗?或者客户端和服务器之间会有一个恒定的连接(即连接的生命周期是从客户端代理实例的创建到客户端代理实例的处置)?

我正在使用基本的HttpBinding。

4

4 回答 4

5

当底层通道关闭时,连接将关闭 - 默认情况下,BasicHttpBinding 在消息中发送一个带有 Keep-Alive 值的连接 HTTP 标头,这使客户端能够与支持它们的服务建立持久连接。

这并不意味着服务的实例保持活动状态,只是与 Web 服务器的连接(如果 Web 服务器支持)。

如果您希望在每次调用后关闭连接,那么您可以通过定义自定义绑定在服务器端将其关闭

<services> 
 <service>
  <endpoint address=""
        binding="customBinding"
        bindingConfiguration="HttpBinding" 
        contract="IContract" />
 </service>
</services>

<bindings>
 <customBinding>
   <binding name="HttpBinding" keepAliveEnabled="False"/>
 </customBinding>
</bindings>

连接将根据您的代理挂起的时间关闭,如果需要,生成的代理将再次重新打开它。

于 2009-08-15T18:30:50.587 回答
3

那么,每次我进行方法调用时,它会建立一个新的连接吗?

是的,这是默认行为和首选行为 - 它为您节省了很多悲伤!

“这并不意味着服务的实例保持活动状态” - 你的意思是“服务的实例保持活动状态”?

在“每次调用”服务的默认和首选情况下,会发生以下情况:

  • 客户端代理发出对服务的调用
  • 消息在客户端序列化并通过网络发送
  • 服务器端有一个“通道侦听器”,它将接收该消息并查看哪个服务类将处理呼叫
  • 服务器端的消息调度程序将实例化“YourServiceClass”的实例
  • 服务器端的消息调度程序现在将在新创建的服务类实例上调用该方法,并获取结果并将它们打包以用于响应
  • 服务器端的服务类对象被释放
  • 响应被发送回您的客户

这就是你的服务类应该尽可能精简、尽可能独立于其他任何东西的原因之一——它们通常会在每个请求进入时被实例化,然后被释放。

这似乎是一个非常糟糕的主意 - 但如果您有服务对象实例徘徊更长的时间,您将不得不做很多簿记以跟踪它们的状态等等,所以最后,它实际上是更容易(通常更安全和更简单)创建服务类,让它处理请求,然后再次释放它。

马克

于 2009-08-16T11:25:26.303 回答
2

George,要考虑的一件事是,您的代码应该尽量不关心连接如何、是否或何时打开或关闭。这主要是通道的关注点,通道应该能够按照它认为合适的方式管理连接,而不必担心您编写的代码取决于通道如何“管理自己的业务”。

只有当您看到或怀疑存在性能问题时,您才应该担心这样的实现细节。如果您担心可能存在这样的问题,请创建一个快速的概念验证应用程序,并使用 Fiddler 或其他工具观察网络流量。在大多数情况下,这将是浪费时间。

于 2009-08-16T01:29:51.633 回答
0

连接一直保持,直到代理被释放。

编辑

至少如果您使用可靠的消息传递,它将保持 TCP 连接打开。我基于此,如果 TCP 连接丢失,可靠的消息传递会失败。看:

http://codeidol.com/csharp/wcf/WCF-Essentials/Reliability/

编辑 2

我收回关于 using 语句的评论。看:

http://msdn.microsoft.com/en-us/library/aa355056.aspx

有点离题,但我们已经停止使用添加服务引用,而是使用此处描述的方法:

http://www.dnrtv.com/default.aspx?showNum=103

注意:这仅在您同时控制客户端和服务器时才有效。

于 2009-08-15T17:59:48.250 回答