简体   繁体   English

WCF客户端连接问题

[英]WCF client connection issue

I am using VSTS2008 + C# + .Net 3.5 to develop WCF service hosted in IIS. 我正在使用VSTS2008 + C#+ .Net 3.5来开发IIS中托管的WCF服务。 Then I generate client proxy code automatically by using Add Service Reference function from VSTS 2008. 然后,我使用VSTS 2008中的“添加服务引用”功能自动生成客户端代理代码。

My question is, suppose I create a client proxy instance, then use this specific instance to call various methods exposed by WCF service at server side. 我的问题是,假设我创建了一个客户端代理实例,然后使用此特定实例来调用服务器端WCF服务公开的各种方法。 Then, each time I make a method call will it establish a new connection? 那么,每次我进行方法调用时都会建立一个新连接吗? Or there will be a constant connection between client and server (ie, the life time of the connection is from creation of the client proxy instance, to the disposal of the client proxy instance)? 或者客户端和服务器之间会有一个持续的连接(即连接的生命周期是从创建客户端代理实例到处理客户端代理实例)?

I am using basicHttpBinding. 我正在使用basicHttpBinding。

The connection will be closed when the underlying channel closes - by default, the BasicHttpBinding sends a connection HTTP header in messages with a Keep-Alive value, which enables clients to establish persistent connections to the services that support them . 当底层通道关闭时,连接将被关闭 - 默认情况下,BasicHttpBinding在具有Keep-Alive值的消息中发送连接HTTP头,这使客户端能够建立与支持它们的服务的持久连接。

This doesn't mean an instance of the service is kept alive, just the connection to the web server, if the web server supports it. 这并不意味着服务实例保持活动,只是与Web服务器的连接,如果Web服务器支持它。

If you want the connection to close after every call then you can turn it off on the server side by defining a custom binding thus 如果要在每次调用后关闭连接,则可以通过定义自定义绑定在服务器端将其关闭

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

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

Connections will close depending on how long your proxy hangs around for, and the generated proxy will reopen it again if it needs to. 连接将根据代理挂起的时间关闭,生成的代理将在需要时再次重新打开它。

Then, each time I make a method call will it establish a new connection? 那么,每次我进行方法调用时都会建立一个新连接吗?

Yes, that's the default behavior and the preferred behavior - it saves you a lot of grief! 是的,这是默认行为和首选行为 - 它可以为您节省很多悲伤!

"This doesn't mean an instance of the service is kept alive" -- what do you you mean "an instance of the service is kept alive"? “这并不意味着服务的实例保持活跃” - 你是什么意思“服务实例保持活着”?

In the default and preferred case of a "per-call" services, this is what happens: 在“每次呼叫”服务的默认和首选情况下,会发生以下情况:

  • the client proxy issues a call to the service 客户端代理发出对服务的调用
  • the message is serialized on the client side and sent across the wire 消息在客户端序列化并通过线路发送
  • the server side has a "channel listener" which will pick up that message and see which service class will handle the call 服务器端有一个“通道监听器”,它将接收该消息并查看哪个服务类将处理该呼叫
  • the message dispatcher on your server side will instantiate an instance of "YourServiceClass" 服务器端的消息调度程序将实例化“YourServiceClass”的实例
  • the message dispatcher on the server side will now call that method on the newly created service class instance, and grab the results and package them up for the respose 服务器端的消息调度程序现在将在新创建的服务类实例上调用该方法,并获取结果并将其打包以进行调整
  • the service class object on the server side is freed 服务器端的服务类对象被释放
  • the response is sent back to your client 响应将发送回您的客户端

That's one of the reasons that your service classes should be as lean, as independent of anything else as possible - they'll typically be instantiated for each request coming in, and freed afterwards. 这是您的服务类应该尽可能独立于其他任何内容的原因之一 - 它们通常会针对每个请求进行实例化,然后释放。

This may seem like a really bad idea - but if you had service object instances lingering around for a longer time, you'd have to do a lot of bookkeeping in order to track their state and so on, so in the end, it's actually easier (and in general a lot safer and simpler) to create a service class, let it handle the request, and then free it again. 这可能看起来是一个非常糟糕的主意 - 但是如果你的服务对象实例徘徊了很长时间,你必须做大量的簿记才能跟踪他们的状态等等,所以最后,它实际上是更容易(并且通常更安全和更简单)创建服务类,让它处理请求,然后再次释放它。

Marc

George, one thing to consider is that your code should try not to care about how, if, or when, the connection opens or closes. 乔治,需要考虑的一件事是你的代码应该尽量不关心连接打开或关闭的方式,时间或方式。 That's primarily the concern of the channel, and the channel should be able to manage the connection as it sees fit, without having to worry that you've written code that depends on how the channel "minds its own business". 这主要是渠道的关注点,渠道应该能够按照自己的意愿管理连接,而不必担心您编写的代码取决于渠道如何“关注自己的业务”。

Only if you see, or suspect, a performance problem, should you worry about implementation details like this. 只有当您看到或怀疑性能问题时,您才应该担心这样的实现细节。 If you're concerned that there might be such a problem, then create a quick proof of concept application, and watch the network traffic with Fiddler or some other tool. 如果您担心可能存在此类问题,请创建快速概念验证应用程序,并使用Fiddler或其他工具观察网络流量。 In most cases, that will be a waste of time. 在大多数情况下,这将是浪费时间。

The connection is held until the proxy is disposed. 连接一直持续到代理处理完毕。

EDIT 编辑

It will keep the TCP connection open, atleast if you use reliable messaging. 如果您使用可靠的消息传递,它将保持TCP连接打开。 I base this on, that reliable messaging fails if the TCP connection is lost. 我的基础是,如果TCP连接丢失,可靠的消息传递将失败。 See: 看到:

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

EDIT 2 编辑2

I take back the comment about the using statement. 我收回有关using语句的评论。 See: 看到:

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

A little off topic, but we have stopped using the Add Service Reference, instead we use the method describe here: 有点偏离主题,但我们已停止使用添加服务引用,而是使用此处描述的方法:

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

Note: This only works if you have control over both the client and the server. 注意:这仅在您控制客户端和服务器时才有效。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM