下面的文字是对这个问题的扩展和添加颜色的努力:
如何防止行为不端的客户取消整个服务?
我基本上有这种情况:WCF 服务启动并运行,客户端回调具有直接、简单的单向通信,与这个没有太大不同:
public interface IMyClientContract
{
[OperationContract(IsOneWay = true)]
void SomethingChanged(simpleObject myObj);
}
我从服务到最终将有大约 50 个并发连接的客户端每秒可能数千次调用此方法,并具有尽可能低的延迟(<15 ms 会很好)。这工作正常,直到我在连接到服务器的一个客户端应用程序上设置一个断点,然后在服务挂起大约 2-5 秒后一切都挂起,并且在服务挂起之前大约 30 秒左右没有其他客户端接收任何数据注册连接故障事件并断开有问题的客户端。在此之后,所有其他客户端继续以愉快的方式接收消息。
我已经对 serviceThrottling、并发调整、设置线程池最小线程、WCF 秘诀和整个 9 码进行了研究,但归根结底,这篇文章MSDN - WCF essentials, One-Way Calls, Callbacks and Events 准确地描述了我在没有真正提出建议的情况下遇到的问题。
允许服务安全回调客户端的第三种解决方案是将回调合约操作配置为单向操作。这样做可以使服务即使在并发设置为单线程时也可以回调,因为不会有任何回复消息来争夺锁。
但在本文前面,它仅从客户的角度描述了我所看到的问题
当单向调用到达服务时,它们可能不会一次全部调度,可能会在服务端排队等待一次调度,这一切都取决于服务配置的并发模式行为和会话模式。服务愿意排队多少条消息(无论是单向还是请求-回复)是配置的通道和可靠性模式的产物。如果排队的消息数量超过了队列的容量,那么客户端将阻塞,即使发出单向调用也是如此
我只能假设反之亦然,发送到客户端的排队消息数量已超过队列容量,并且线程池现在充满了试图调用该客户端的线程,这些线程现在都被阻塞了。
处理这个问题的正确方法是什么?我是否应该研究一种方法来检查每个客户端在服务通信层排队的消息数量,并在达到一定限制后中止它们的连接?
几乎看起来,如果 WCF 服务本身在队列填满时阻塞,那么每当一个客户端的队列满时,我可以在服务中实现的所有异步/单向/即发即弃策略仍然会被阻塞。