如何正确配置WCF NetTcp双工可靠会话?
请原谅明显的自我问答,但这一信息被广泛误解,而且几乎总是回答错误。所以我想把这些信息放在这里,供人们寻找这个问题的最终答案 即便如此,仍有一些信息我无法确定。我将把这一点放在问题的末尾(如果您对序言不感兴趣,请跳到这一点) 如何正确配置WCF NetTcp双工可靠会话? 关于这个主题有很多问题和答案,几乎所有的问题和答案都建议在您的配置中设置如何正确配置WCF NetTcp双工可靠会话?,wcf,configuration,duplex-channel,Wcf,Configuration,Duplex Channel,请原谅明显的自我问答,但这一信息被广泛误解,而且几乎总是回答错误。所以我想把这些信息放在这里,供人们寻找这个问题的最终答案 即便如此,仍有一些信息我无法确定。我将把这一点放在问题的末尾(如果您对序言不感兴趣,请跳到这一点) 如何正确配置WCF NetTcp双工可靠会话? 关于这个主题有很多问题和答案,几乎所有的问题和答案都建议在您的配置中设置inactivityTimeout=“Infinite”。这似乎并没有真正正确地工作,特别是对于NetTcp(它可能对WSDualHttp绑定正常工作,但我
inactivityTimeout=“Infinite”
。这似乎并没有真正正确地工作,特别是对于NetTcp(它可能对WSDualHttp绑定正常工作,但我从未使用过这些绑定)
还有许多其他问题通常与此相关:包括在客户端或服务器意外断开连接后通道未出现故障、10分钟后通道断开连接、通道随机断开连接。。。尝试打开时发生频道引发异常。。。无法在同一终结点上配置元数据
请注意:下面有两个概念很重要。基础结构消息是WCF通信方式的内部消息,框架使用这些消息来保持事情的平稳运行。操作消息是由于应用程序执行了某些操作(如通过网络发送消息)而出现的消息。应用程序基本上看不到基础结构消息(但它们仍然出现在后台),而操作消息则是应用程序已采取的操作的结果
通过来之不易的尝试和错误,我找到了信息
并不是在所有情况下都是有效的配置设置(当然,VisualStudio验证模式并不知道这一点)Infinite
- 有两种特殊的配置转换器,分别称为
和InfiniteIntConverter
,它们有时用于将值InfiniteTimeSpanConverter
转换为Infinite
或Int.MaxValue
,但我还没有弄清楚在什么情况下这似乎是有效的,因为它有时有效,有时无效。此外,似乎有些库在配置中允许TimeSpan.MaxValue
,而其他库则不允许,因此您可以在配置的一部分中成功,但在另一部分中失败Infinite
- 您必须在客户端和服务器上同时配置
和inactivityTimeout
。虽然这些值不必相同,但它们可能应该相同,因为如果不相同,它们可能会引起混淆。(从技术上讲,如果需要,您可以将receiveTimeout
保留为其默认值,但您应该了解其值及其作用)inactivityTimeout
不应设置为大值,更不应设置为inactivityTimeout
或Infinite
TimeSpan.MaxValue
有两个功能(这一点还没有被广泛理解)。第一个函数定义在不接收任何“基础设施”或“操作”消息的情况下,在通道上可以经过的最大时间量。第二个函数定义发送基础结构消息的时间段(指定时间的一半)。如果在超时期间未收到任何基础结构或操作消息,则会中止连接inactivityTimeout
仅指定操作消息之间可以经过的最大时间量。此值可以设置为较大的值,例如receiveTimeout
(特别是当您的频道在内部通过可信网络或vpn运行时)。此值定义了如果客户端和服务器之间没有活动(基础结构消息除外),可靠会话将“保持活动”的时间。也就是说,您的客户机不调用接口的任何方法,并且您的服务器也不回调客户机李>TimeSpan.MaxValue
- 设置较短的
和较大的inactivityTimeout
即使在客户端和服务器之间没有操作活动的情况下,也可以保持可靠的会话“固定”。短的非活动超时(我喜欢保持默认的10分钟或更少)发送基础结构“ping”消息以保持TCP连接的活动,而长的接收超时保持可靠会话的活动。同时在断开连接时提供合理的超时时间receiveTimeout
- 如果将
设置为较大的值,则可靠会话将不可靠,因为它无法保持Tcp连接的活动状态,也无法验证连接的完整性。它不会知道用户是否意外断开连接,直到您尝试向该客户端发送消息并发现连接已不存在。这就是为什么许多使用Infinite进行此设置的人求助于在其服务中创建“Ping”方法的原因,如果您正确配置了这些设置,则完全没有必要这样做inactivityTimeout
- 如果将
设置为大于inactivityTimeout
的值,则同样不可靠,因为操作消息仍受receiveTimeout
的控制。例如,如果忘记设置receiveTimeout
,并将其保留为默认的10分钟,那么如果用户空闲10分钟,连接将中止receiveTimeout
- 当客户端或服务器意外断开连接时(应用程序崩溃、网络故障、有人被电源线绊倒等),另一方可能不会立即注意到。我在各种测试情况下附加了各种
事件处理程序,有时连接会立即出现故障。。。其他时候是这样的ChannelFaulted