14

我正在使用 WCF 在 .Net 3.5 中开发客户端/服务器应用程序。基本上,长时间运行的客户端服务(在多台机器上)通过 netTcpBinding 建立到服务器的双工连接。然后服务器使用客户端的回调合约来执行某些按需操作,客户端以异步方式响应(我认为这是相当标准的东西)。我将 DuplexClientBase 类子类化以处理大部分通信。

不幸的是,当任一端出现问题(例如网络故障、意外异常等)时,通道会出现故障/中止,并且所有后续操作都会失败。我通过创建一个 RecoveringClientBase 类解决了非双工通道中的这一限制,该类在客户端出现故障时自动获取并重试操作。

所以我的问题是,是否有确定双工通道何时出现故障的既定方法?我应该在哪里检查这个,在服务器或客户端上?如果做不到这一点,我必须有哪些选项来确保重新建立连接?

更新:我正在寻找一些特定于双工通道的建议,其中服务器可能会尝试使用出现故障的回调通道。因此,我需要在频道发生问题时立即重新连接/重新订阅的东西。目前,我正在收听频道的 Closing 事件,如果状态不是已关闭,则重新创建它。它有点工作,但感觉很hacky......

4

4 回答 4

3

我在长时间运行的会话(几分钟-几小时)中经历过片状。我不能确定它是 WCF,我很确定它的网络级别。

我正在考虑完全取消双工。尝试管理连接状态是一件非常麻烦的事情。

我正在考虑在客户端上托管一个服务端点,用于当前属于回调合同的操作。客户端将使用端点详细信息联系服务器,服务器可以将这些存储在某个地方(持久或任何地方)。当服务器需要联系客户端时,它会通过隐藏的端点详细信息打开与客户端的连接。基本上,将双工连接变成 2 个客户端-服务器连接。

没有回答你的问题,但我能感觉到你的痛苦。

于 2009-01-09T22:00:32.263 回答
1

WCF 团队的 Nicolas Allen 对此提出了建议:

http://blogs.msdn.com/drnick/archive/2007/11/05/custom-transport-retry-logic.aspx

他的建议是在渠道层面处理这个问题。通道级别更好一些,因为您可以通过行为将其插入任何绑定的堆栈,而不需要自定义客户端基类。

于 2008-10-15T14:28:13.987 回答
0

我遇到过一些类似的问题,在我看来,这些长时间运行的调用或多或少不受支持。

WCF 似乎被设计为用于短期运行的调用。服务,被调用,做一些小事情,然后完成。

我将我的应用程序重构为更小的工作项。因此,我现在得到了许多较小的项目,而不是一件长期运行的大型项目。当然,有时这是不可能实现的。然后我必须为稳定的网络连接祈祷(可以捕捉到异常,所以我认为故障并不是真正的问题)。

于 2009-01-07T15:16:46.640 回答
0

我认为你真的应该听听错误的事件。您可以在两端收听,客户端我认为您已经在处理,服务器端是 OperationContext.Current.Channel.events。

我还没有找到一种自动重新发送消息的方法,因为您的回调通道已经出现故障并且您还不知道新的回调通道,但需要将这些调用保留在服务器的某个位置,直到客户端重新连接。

客户端最终会出现故障,应该重新与服务器握手,服务器应该发出未发送的调用。

基本上,从故障/关闭通道中恢复的唯一方法是用新通道替换它,但是,最关键的部分是您应该真正检测到断开连接,我发现启用可靠会话将在大多数情况下按时引发故障事件案子。或者,您可以在两端发送心跳消息到“测试”通道故障。

于 2011-01-18T07:26:17.367 回答