WCF客户端连接问题

WCF客户端连接问题

问题描述:

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

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

我正在使用basicHttpBinding。

连接被保留,直到代理被处置。

编辑

这将保持TCP连接开放,至少如果你使用可靠的消息。我的基础是,如果TCP连接丢失,可靠的消息传递将失败。请参阅:

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

EDIT 2

我收回对使用声明的评论。请参阅:

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

有点偏离主题,但我们已经使用添加服务引用停止,取而代之的是我们使用的方法在这里描述:

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

注:这仅适用于如果您可以控制客户端和服务器。

+0

谢谢,这是否意味着底层TCP连接保持打开(活动),直到代理处置? – George2 2009-08-15 18:03:21

+3

不,你不应该。在使用中包装代理是一个糟糕的主意,好像Dispose在处于故障状态的代理上被调用,然后它会抛出一个异常,从而首先隐藏导致错误的异常。 – blowdart 2009-08-15 18:16:16

+0

谢谢Shiraz,如果我没有使用可靠的消息传递并且只使用basicHttpBinding的默认设置,底层连接是否会一直存在?或者每次我们调用一个方法都会有一个新的连接? – George2 2009-08-15 18:18:08

当底层信道关闭时,连接将被关闭 - 默认情况下,basicHttpBinding的与保持活动值,这使得客户建立到支持它们服务持续连接消息发送连接HTTP标头。

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

如果你想连接到每一个呼叫后关闭,那么你可以通过定义一个定制的结合从而

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

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

连接关闭它在服务器端将关闭根据您的代理是如何长挂周围,如果需要,生成的代理将重新打开它。

+0

谢谢!两个混淆,1。“这并不意味着服务的一个实例保持活着” - 你是什么意思“服务的一个实例是活着的”? 2.“如果网络服务器支持它。” - 对于IIS,如何检查是否支持? – George2 2009-08-16 05:13:14

+0

对不起2个更多的混淆, 3.“和生成的代理将重新打开它,如果需要。” - 底层WCF将自动处理它,并且如果连接关闭并再次重新打开,则不会抛出异常?开发人员无需处理这种情况? 4.“连接将关闭,取决于代理挂起的时间” - 是否可配置? – George2 2009-08-16 05:14:48

+1

“服务实例”是指实现服务合约的类的Web服务器计算机上的实例。有些人认为在创建代理实例时会创建服务实例。这不是真的。 – 2009-08-16 05:18:22

乔治,要考虑的一件事是,你的代码应该尽量不关心连接打开或关闭的方式,时间或时间。这主要是渠道关注的问题,渠道应该能够在合适的情况下管理连接,而不必担心自己编写的代码取决于渠道“如何管理自己的业务”。

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

+0

谢谢约翰,我完全同意你的看法。目前我在将大量数据从服务器传输到客户端时遇到了一个问题。这是我的问题,http://*.com/questions/1281269/response-size-limitaiton-of-a-wcf-web-serivces我怀疑openTimeout参数是否导致这个问题,我想我需要知道每次我进行方法调用时是否需要建立连接或者只需打开一次。如果只打开一次,这个参数不应该引起这个问题,因为我在这个错误方法调用之前做了一些成功的方法调用,但是如果每次连接都需要建立 – George2 2009-08-16 05:37:55

+0

(续),我认为这个参数可能会影响结果。对于这个参数的任何注释,或者每次方法调用发生或只发生一次连接是否需要建立? – George2 2009-08-16 05:38:36

+1

即使需要多次建立自己,每次都会使用配置的参数。 – 2009-08-16 05:42:42

然后,每次我做一个方法调用它会建立一个新的连接?

是的,这是默认行为和首选行为 - 它可以为您节省很多的痛苦!

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

在默认和“每呼叫”服务优先的情况下,这是发生了什么:

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

这就是你的服务类应尽可能瘦的原因之一,因为别的尽可能独立 - 他们通常会为每个进入的请求实例化,然后释放。

这似乎是一个非常糟糕的主意 - 但如果服务对象实例徘徊了很长时间,则必须进行大量的簿记才能跟踪其状态等等,因此在最后,它实际上更容易(并且通常更安全和更简单)来创建服务类,让它处理请求,然后再次释放它。

Marc

+0

嗨,马克,我很困惑。从与blowdart的讨论看来,似乎保持活力是默认行为,如果保持活跃状态​​,则在我们进行第一次方法调用时应该只建立一次连接,而在每次进行方法调用时都不会打开/关闭。任何意见? – George2 2009-08-17 12:33:55