WCF 双工客户端的最佳实践

Posted

技术标签:

【中文标题】WCF 双工客户端的最佳实践【英文标题】:Best practice for WCF Duplex client 【发布时间】:2012-02-25 21:09:22 【问题描述】:

我不能否认双工异步调用的性能优势,但有些事情让我感到警惕。

我担心的是,给定一个实例化的客户端对象,WCF 是否能够判断哪个特定的客户端服务实例将接收回调参数?

谁能告诉我这是否是个好主意?如果不是为什么不呢?

new DuplexChannelFactory<IServerWithCallback>(
   new ClientService(), 
   new NetTcpBinding(), 
   new EndpointAddress("net.tcp://localhost:1234/"+Guid.NewGuid()))

    如果上面的虚拟路径是保留的,如何丢弃它。我希望客户服务的生命周期相当短。 IE 发出请求并接收响应,完成接收后将其杀死。缩短客户端服务生命周期与将其池化并使其保持更长的生命周期相比,性能损失有多严重。

    这个想法是为了避免超时问题。完成接收、发送后,尽快处理。按照惯例 - 不能传递客户端服务。如果您需要信息,请创建一个新的,简单的 - 就像 EF/L2S 等。

    如何从 WCF 服务本身内部终止与客户端的会话。 IE。我不希望客户端结束会话 - 我知道我可以相应地装饰我的操作,但我希望服务在满足某些条件时以编程方式自行终止。

    我可以附加端口并相应地转发以解决任何防火墙问题,但我担心的是客户端是否位于负载平衡器后面。服务如何知道要调用哪个特定服务器?

【问题讨论】:

【参考方案1】:

我认为最终双工服务只是微软的另一个失败的架构。这是在纸上看起来非常好的东西之一,但仔细检查后就崩溃了。

缺点太多了:

1) 服务器依赖会话建立客户端监听器。这是会话信息存储在内存中。因此,服务器本身无法进行负载平衡。或者如果它是负载平衡的,您需要打开 ip affinity,但现在如果其中一台服务器被轰炸,您不能简单地添加另一台服务器并期望所有这些会话自动迁移到新服务器。

2) 对于位于路由器/防火墙/负载均衡器后面的每个客户端,需要创建一个具有特定端口的新端点。否则路由器将无法正确地将回调消息路由到适当的客户端。另一种方法是拥有一个允许自定义编程将特定路径重定向到特定服务器的路由器。又是一个艰巨的任务。或者另一种方法是让具有回调的客户端托管自己的数据库并通过数据库共享数据

3) 所有这些基本上都说明双工实际上是无用的。如果您需要回电,那么您最好在客户端设置一个 wcf 主机。它将更简单,更具可扩展性。此外,客户端和服务器之间的耦合更少。

可扩展架构的最佳双工解决方案最终还是不用一个。

【讨论】:

这个答案是否适用于 NetTcpBinding 或仅适用于双 Http 绑定?【参考方案2】:

    这将取决于您需要新客户多长时间以及他们将持续多长时间。如果您每次都特别需要一个新客户端,则池不是一个选项,但如果客户端继续做同样的事情,为什么不让它们的池等待使用,如果它们出现故障再次重新创建同一个客户端。

    实际上,在回调场景中,如果服务回调客户端(实际上是调用客户端上的函数)以传递信息,则服务现在是客户端,反之亦然。您可以让服务进行回调 .Close() 连接,但它会一直打开,直到 GC 可以处理它,根据我的经验,这可能需要比预期更长的时间。所以简而言之,客户端应该负责(客户端是调用某事的人)自行关闭或断开连接,服务应该只返回答案或从客户端获取数据。

    在双工回调中,现在回调客户端的服务将获得在双工通道工厂后面抽象出来的客户端地址。如果服务无法回调客户端,我认为没有什么可以做的,你必须确保你的客户端调用服务的端口是开放的,以接收我猜的回调。

【讨论】:

以上是关于WCF 双工客户端的最佳实践的主要内容,如果未能解决你的问题,请参考以下文章

启用缓存时模拟服务人员和 Apollo 客户端的最佳实践

apache Apache Airflow/Cloud Composer 中多个客户端的最佳实践?

Android最佳实践——深入浅出WebSocket协议

GWT 将大量数据从服务器发送到客户端的最佳实践

.Net WCF NAT 遍历的最佳实践

大数据最佳实践 | HBase客户端(上)