保持 wcf 回调通道无限期打开/如果出现故障则从客户端重新连接

Posted

技术标签:

【中文标题】保持 wcf 回调通道无限期打开/如果出现故障则从客户端重新连接【英文标题】:keeping a wcf callback channel open indefinitely / reconnecting from client if it faults 【发布时间】:2011-07-21 07:50:51 【问题描述】:

我目前正在尝试设置这样的东西:

服务器端 Windows wcf 服务挂起并通过 tcp 侦听来自客户端 Windows 服务的连接。 当接收到连接时(客户端调用服务上的 CheckIn 方法),服务通过 OperationContext.Current.GetCallbackChannel 获取回调通道 此通道与唯一键一起存储在集合中(具体来说,我将回调接口、通道和键存储在 List 中,其中每一个都是一个属性) 现在应该能够根据所述唯一键将调用传递给该客户端服务

这起初有效,但一段时间后停止 - 我不再能够将呼叫传递给客户端。我假设这是因为连接已在内部断开,我正在尝试使用死连接。

记住,我有以下问题:

我如何告诉 wcf 我想无限期地(或尽可能长地)保持这些 tcp 连接? 如何从客户端检查我与服务器的连接是否仍然有效,以便在我的连接中断时将其删除并再次与服务器签入?

我能想到 gimpy 解决方案,但我希望这里有人能告诉我正确的方法。

【问题讨论】:

只是给大家一些信息——我们最终没有使用 WCF 作为我们的解决方案,因为我们正在编写一个潜在的高流量服务器应用程序并且有很多事情要处理。我们遇到了一些性能问题,我们的服务器应用程序在某个时候崩溃了。可能可以修复,但我们最终改用 RabbitMQ。 感谢提到RabbitMQ,我不熟悉。 【参考方案1】:

当您从客户端建立连接时,您应该在您的 tcp 绑定中设置两个超时值(您将传递给 ClientBase 或 DuplexClientBase 的绑定):

NetTcpBinding binding = new NetTcpBinding();
binding.ReceiveTimeout = TimeSpan.FromHours(20f);
binding.ReliableSession.InactivityTimeout = TimeSpan.FromHours(20f);

我的示例使用 20 小时超时,您可以使用对您有意义的任何值。然后 WCF 将尝试在这段时间内保持您的客户端和服务器连接。默认值相对较短(可能是 5 分钟?)并且可以解释您的连接断开的原因。

只要客户端和服务器之间出现通信问题(包括 WCF 本身丢弃通道),WCF 就会在客户端中引发故障事件,您可以处理该事件以执行任何您认为合适的操作。在我的项目中,我将 DuplexClientBase 派生对象转换为 ICommunicationObject 以获取 Faulted 事件并将其转发给在我的类中公开的名为 OnFaulted 的事件:

ICommunicationObject communicationObject = this as ICommunicationObject;
communicationObject.Faulted +=
   new EventHandler((sender, e) =>  OnFaulted(sender, e); );

在上面的代码 sn-p 中,this 是我的 WCF 客户端类型的一个实例,在我的例子中它是从 DuplexClientBase 派生的。您在此事件中所做的事情是特定于您的应用程序的。就我而言,应用程序是一个非关键 UI,因此如果出现 WCF 错误,我只需向最终用户显示一个消息框并关闭应用程序 - 如果它总是这么简单,那将是一个美好的世界!

【讨论】:

这似乎可行。当我完成测试后,我会告诉你结果如何! 你能解释一下在哪里写下面的代码以及在 OnFaulted 事件中做什么?我的意思是在发生错误的客户端或服务器端! ICommunicationObject communicationObject = this as ICommunicationObject; communicationObject.Faulted += new EventHandler((sender, e) => OnFaulted(sender, e); ); @KomalJariwala 通信对象.Faulted 事件在客户端可用,来自您的 ClientBase 派生对象。我编辑了上面的答案以澄清这一点,并解释我可以在我自己的 OnFaulted 实现中使用的简单代码。 但是服务器端故障器呢?如果这发生在客户端,我可以重新连接。但服务器看起来无法在 Duplex 中重新连接。 服务器不可能重新连接到客户端——除非客户端被公开。

以上是关于保持 wcf 回调通道无限期打开/如果出现故障则从客户端重新连接的主要内容,如果未能解决你的问题,请参考以下文章

WCF - 长时间打开通道是不好的做法吗?

如果出现故障,如何自动重新建立双工通道?

不活动后出现错误的 WCF 双工回调 - 保持活动长时间运行的推送通知

Wcf 回调网络 tcp 双工仅 1 路故障

WCF 通道故障状态是不是有帮助?

重复调用的 WCF 通道生命周期