如何正确配置WCF NetTcp双工可靠会话?

如何正确配置WCF NetTcp双工可靠会话?,wcf,configuration,duplex-channel,Wcf,Configuration,Duplex Channel,请原谅明显的自我问答,但这一信息被广泛误解,而且几乎总是回答错误。所以我想把这些信息放在这里,供人们寻找这个问题的最终答案 即便如此,仍有一些信息我无法确定。我将把这一点放在问题的末尾(如果您对序言不感兴趣,请跳到这一点) 如何正确配置WCF NetTcp双工可靠会话? 关于这个主题有很多问题和答案,几乎所有的问题和答案都建议在您的配置中设置inactivityTimeout=“Infinite”。这似乎并没有真正正确地工作,特别是对于NetTcp(它可能对WSDualHttp绑定正常工作,但我

请原谅明显的自我问答,但这一信息被广泛误解,而且几乎总是回答错误。所以我想把这些信息放在这里,供人们寻找这个问题的最终答案

即便如此,仍有一些信息我无法确定。我将把这一点放在问题的末尾(如果您对序言不感兴趣,请跳到这一点)

如何正确配置WCF NetTcp双工可靠会话? 关于这个主题有很多问题和答案,几乎所有的问题和答案都建议在您的配置中设置
inactivityTimeout=“Infinite”
。这似乎并没有真正正确地工作,特别是对于NetTcp(它可能对WSDualHttp绑定正常工作,但我从未使用过这些绑定)

还有许多其他问题通常与此相关:包括在客户端或服务器意外断开连接后通道未出现故障、10分钟后通道断开连接、通道随机断开连接。。。尝试打开时发生频道引发异常。。。无法在同一终结点上配置元数据

请注意:下面有两个概念很重要。基础结构消息是WCF通信方式的内部消息,框架使用这些消息来保持事情的平稳运行。操作消息是由于应用程序执行了某些操作(如通过网络发送消息)而出现的消息。应用程序基本上看不到基础结构消息(但它们仍然出现在后台),而操作消息则是应用程序已采取的操作的结果

通过来之不易的尝试和错误,我找到了信息

  • Infinite
    并不是在所有情况下都是有效的配置设置(当然,VisualStudio验证模式并不知道这一点)
  • 有两种特殊的配置转换器,分别称为
    InfiniteIntConverter
    InfiniteTimeSpanConverter
    ,它们有时用于将值
    Infinite
    转换为
    Int.MaxValue
    TimeSpan.MaxValue
    ,但我还没有弄清楚在什么情况下这似乎是有效的,因为它有时有效,有时无效。此外,似乎有些库在配置中允许
    Infinite
    ,而其他库则不允许,因此您可以在配置的一部分中成功,但在另一部分中失败
  • 您必须在客户端和服务器上同时配置
    inactivityTimeout
    receiveTimeout
    。虽然这些值不必相同,但它们可能应该相同,因为如果不相同,它们可能会引起混淆。(从技术上讲,如果需要,您可以将
    inactivityTimeout
    保留为其默认值,但您应该了解其值及其作用)
  • inactivityTimeout
    不应设置为大值,更不应设置为
    Infinite
    TimeSpan.MaxValue
  • inactivityTimeout
    有两个功能(这一点还没有被广泛理解)。第一个函数定义在不接收任何“基础设施”或“操作”消息的情况下,在通道上可以经过的最大时间量。第二个函数定义发送基础结构消息的时间段(指定时间的一半)。如果在超时期间未收到任何基础结构或操作消息,则会中止连接
  • receiveTimeout
    仅指定操作消息之间可以经过的最大时间量。此值可以设置为较大的值,例如
    TimeSpan.MaxValue
    (特别是当您的频道在内部通过可信网络或vpn运行时)。此值定义了如果客户端和服务器之间没有活动(基础结构消息除外),可靠会话将“保持活动”的时间。也就是说,您的客户机不调用接口的任何方法,并且您的服务器也不回调客户机
  • 设置较短的
    inactivityTimeout
    和较大的
    receiveTimeout
    即使在客户端和服务器之间没有操作活动的情况下,也可以保持可靠的会话“固定”。短的非活动超时(我喜欢保持默认的10分钟或更少)发送基础结构“ping”消息以保持TCP连接的活动,而长的接收超时保持可靠会话的活动。同时在断开连接时提供合理的超时时间
  • 如果将
    inactivityTimeout
    设置为较大的值,则可靠会话将不可靠,因为它无法保持Tcp连接的活动状态,也无法验证连接的完整性。它不会知道用户是否意外断开连接,直到您尝试向该客户端发送消息并发现连接已不存在。这就是为什么许多使用Infinite进行此设置的人求助于在其服务中创建“Ping”方法的原因,如果您正确配置了这些设置,则完全没有必要这样做
  • 如果将
    inactivityTimeout
    设置为大于
    receiveTimeout
    的值,则同样不可靠,因为操作消息仍受
    receiveTimeout
    的控制。例如,如果忘记设置
    receiveTimeout
    ,并将其保留为默认的10分钟,那么如果用户空闲10分钟,连接将中止
  • 当客户端或服务器意外断开连接时(应用程序崩溃、网络故障、有人被电源线绊倒等),另一方可能不会立即注意到。我在各种测试情况下附加了各种
    ChannelFaulted
    事件处理程序,有时连接会立即出现故障。。。其他时候是这样的