WCF TCP客户端 - 如何使用它们的基本指南?

Ran*_*ngy 9 wcf tcp wcf-client

我有一个WCF服务,并希望使用TCP绑定连接到它.这一切都很好,但你应该如何处理客户?我注意到,如果你为每个调用创建一个新的客户端,它不会重新使用该通道,并留下一堆TCP连接,直到它们超时.

创建客户端,在其上调用方法然后关闭它是否正常?

如果您想重新使用连接怎么办?有什么限制?你可以从不同的线程同时拨打电话吗?如果你不能,你是否必须自己建立连接池?当重新使用连接时,您是否必须在拨打电话之前检查连接状态并在出现故障时进行清理?

Lad*_*nka 17

那么这是很多问题,情况真的有点复杂.创建客户端时,您可以通过服务引用和获取派生类来执行此操作,也ClientBase<ServiceContract>可以ChannelFactory<ServiceContract>手动使用和创建通道(前一种情况在内部使用ChannelFactory).

这与你的问题有什么关系?让我们先来看看真正的TCP连接.定义时NetTcpBinding,可以设置其MaxConnections属性(默认值为10).此属性定义池化连接的数量.这意味着如果您创建到服务器的客户端通道并关闭通道,则不会立即终止连接.它在池中保持打开状态,直到它被另一个打开的客户端通道用于同一服务器或其空闲超时到期为止.您可以打开服务器允许的尽可能多的连接,但只有MaxConnections在关闭相关客户端通道时才会汇集由其定义的数字.其他连接将立即终止.如果你创建了CustomBinding你可以直接使用TCP传输,你也可以控制空闲超时(我认为默认是2分钟).只要相关ChannelFactory内容未被销毁,就会汇集连接= ChannelFactory每个应用程序使用一个(ClientBase在内部执行).

现在让我们谈谈频道本身,因为它与您的其他问题有关.WCF不同于会话和无会话通道.TcpTransportChannel是sessionfull.这意味着一旦打开频道,您就会创建一个会话.会话意味着来自单个客户端代理的所有请求默认始终由相同的服务实例(每个会话实例)提供服务.但该实例默认是单线程的.这意味着您可以使用相同的代理拥有多个线程,但该服务将按顺序处理请求.如果您希望服务同时处理多个请求,则必须使用[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple].完成后,您负责服务中的线程安全处理(多个线程访问相同的服务实例).

会话渠道有一个很大的缺点.服务上的任何故障或异常都会破坏通道,并且在您尝试再次使用该通道后,您通常会知道该通道(例外,该通道处于故障状态且无法使用).您必须始终正确处理这些情况,并且必须在不想使用它们时正确关闭通道/代理,或者在出现故障时将其中止.故障通道无法修复 - 必须中止,您必须创建新的代理/通道.如果不这样做,我不确定连接是否返回池.

重用代理/通道取决于您正在构建的应用程序类型.我绝对不会在Web应用程序中的多个请求中重用代理/通道,但在WinForm或WPF应用程序中重用是绝对可以的.

编辑:

是内部ClientBase使用ChannelFactory.使用方式ChannelFactory随着时间的推移而发生了变化.在.NET 3.0中,为每个ClientBase实例创建了工厂.由于.NET 3.5 WCF使用内部MRU缓存(最近使用),缓存最多32个最后使用的工厂.要利用此缓存,您必须使用不带参数的代理构造函数或使用endpointConfigurationNameremoteAddress/ EndpointAddress.您不能在代码中创建端点 - 这些代理不使用缓存.更多的话题是在这里.