我有一个 WCF 服务并希望使用 TCP 绑定连接到它。这一切都很好,但是你应该如何处理客户呢?我注意到,如果您为每个调用创建一个新客户端,它不会重新使用该通道,并会留下一堆 TCP 连接,直到超时。
创建客户端,调用其方法,然后关闭它是正常使用吗?
如果您想重新使用该连接怎么办?对此有何限制?可以从不同线程同时调用吗?如果不能,是否必须自己进行连接池?当重新使用连接时,是否必须在调用之前检查连接状态并在出现故障时进行清理?
嗯,这是很多问题,而且情况确实有点复杂。创建客户端时,您可以通过服务引用并获取派生类来完成此操作ClientBase<ServiceContract>
或者你可以使用ChannelFactory<ServiceContract>
并手动创建通道(前一种情况在内部使用 ChannelFactory)。
这与你的问题有何关系?我们首先看一下真实的 TCP 连接。当你定义NetTcpBinding
你可以设置它的MaxConnections
属性(默认值为 10)。该属性定义池连接的数量。这意味着如果您创建到服务器的客户端通道并关闭该通道,连接不会立即终止。它在池中保持打开状态,直到被同一服务器的另一个打开的客户端通道使用或直到其空闲超时到期。您可以打开服务器允许的任意数量的连接,但仅限由MaxConnections
一旦您关闭相关客户渠道,该费用将被集中。其他连接将立即终止。如果你创建CustomBinding
你可以直接使用TCP传输,你也可以控制空闲超时(我认为默认是2分钟)。只要相关的连接被池化ChannelFactory
没有被破坏=使用一个ChannelFactory
每个应用程序(ClientBase
内部做)。
现在我们来谈谈频道本身,因为它与您的其他问题有关。 WCF 区分会话通道和无会话通道。TcpTransportChannel
是会话满的。这意味着一旦您打开频道,您就创建了一个会话。会话意味着来自单个客户端代理的所有请求默认情况下始终由同一服务实例(每个会话实例)提供服务。但该实例默认是单线程的。这意味着您可以有多个线程使用同一代理,但服务将按顺序处理请求。如果您希望您的服务同时处理多个请求,则必须将其标记为[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple]
。一旦完成,您就负责服务中的线程安全处理(多个线程访问同一服务实例)。
会话通道有一个很大的缺点。服务上的任何故障或异常都会破坏通道,通常在您尝试再次使用该通道后就会知道这一点(例外情况是通道处于故障状态并且无法使用)。您必须始终正确处理这些情况,并且在不想使用通道/代理时必须正确关闭它们,或者在它们出现故障时中止它们。有故障的通道无法修复 - 必须中止它,并且您必须创建新的代理/通道。如果您不这样做,我不确定连接是否会返回到池中。
重用代理/通道取决于您正在构建的应用程序的类型。我绝对不会在 Web 应用程序中的多个请求中重用代理/通道,但在 WinForm 或 WPF 应用程序中重用是绝对可以的。
Edit:
Yes ClientBase
uses ChannelFactory
内部。方式如何ChannelFactory
用途随着时间的推移而改变。在 .NET 3.0 中,工厂是为每个ClientBase
实例。由于 .NET 3.5 WCF 使用内部 MRU 缓存(最近使用的),它最多可缓存 32 个最近使用的工厂。要利用此缓存,您必须使用不带参数或带参数的代理构造函数endpointConfigurationName
and remoteAddress
/ EndpointAddress
。您不得在代码中创建端点 - 这些代理不使用缓存。有关该主题的更多信息是here http://blogs.msdn.com/b/wenlong/archive/2007/10/27/performance-improvement-of-wcf-client-proxy-creation-and-best-practices.aspx.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)