c# - KeepAlive 与 WCF 和 TCP?

标签 c# wcf tcp keep-alive

我有一个 Windows 服务托管一个高级 WCF 服务,该服务通过 TCP(netTCP) 与 protobuf.net 通信,有时还与证书通信。

receiveTimeout 设置为无限,永远不会因不活动而断开连接。但据我所知,无论如何连接都可能被断开,所以我创建了一个简单的双向 keepalive 服务方法,客户端每 9 分钟调用一次以保持连接有效。连接永不中断非常重要。

这是正确的方法吗?或者我是否可以因为 receiveTimout 设置为无限而简单地删除我的 keep live?

编辑:WCF 服务的当前 app.config:http://1drv.ms/1uEVKIt

最佳答案

没有。这被广泛误解,不幸的是,那里有很多错误信息。

首先,“无限”是一种半有效值。有两个特殊的配置序列化程序可以将“Infinite”转换为 TimeSpan.MaxValue。或 int.MaxValue (所以无论如何它们都不是真正的“无限”),但并不是 WCF 中的所有内容似乎都认识到这一点。所以最好用时间值明确指定超时。

其次,您的服务中不需要“keepalive”方法,因为 WCF 提供了所谓的“可靠 session ”。如果添加 <reliableSession enabled="true" />然后 WCF 将通过“基础结构消息”提供它自己的保持事件机制。

通过拥有自己的“keepalive”机制,您可以有效地将服务负载加倍,而且实际上制造的问题多于解决的问题。

第三,在使用可靠 session 时,您使用 inactivityTimeout reliableSession 的设置.这有两件事。首先,它控制发送基础设施(保持事件)消息的频率。它们以超时值的一半发送,因此如果您将其设置为 18 分钟,那么它们将每 9 分钟发送一次。其次,如果在不活动超时内没有收到基础设施或操作消息(即作为数据契约(Contract)的一部分的消息),则连接将中止,因为可能存在问题(一侧已崩溃,存在网络问题等)。 .).

receiveTimeout是连接中止之前无法接收到任何操作消息的最长时间(默认为 10 分钟)。将其设置为较大的值(Int32.MaxValue 接近 24 天)保持连接稳定,将 inactivityTimeout 设置为较小的值(同样,默认值为 10 分钟)(小于 2x 的时间网络路由器因不活动而断开连接之前的最长时间)保持连接有效。

WCF 为您处理所有这一切。然后,您可以简单地订阅“连接中止”消息,以了解连接何时因真正原因(应用程序崩溃、网络超时、客户端断电等)而断开,并允许您重新创建连接。

此外,如果您不需要有序消息,请设置 ordered="false" ,因为这大大减少了可靠 session 的开销。默认为真。

注意:在 inactivityTimeout 过期(或您尝试使用连接)之前,您可能不会收到连接中止事件。请注意这一点,并相应地设置超时。

互联网上的大多数建议都是将 receiveTimeout 和 inactivityTimeout 都设置为 Infinite。这有两个问题,第一个基础设施消息没有及时发送,所以路由器会断开连接……迫使你做自己的保活。其次,长时间的不活动超时意味着它无法识别连接何时合法断开,您必须依靠 ping 中止来了解何时发生故障。这完全没有必要,实际上甚至会使您的服务更加不可靠。

另见:How do I correctly configure a WCF NetTcp Duplex Reliable Session?

关于c# - KeepAlive 与 WCF 和 TCP?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26732515/

相关文章:

c# - 如何在不使用编程语言的装箱支持的情况下将值设为 "box"?

xml - 根据 XML 请求更改 WCF 命名空间

wcf - 在 C# 中滚动一个简单的 ESB/发现服务?

java - 为什么我的客户端不再接受输入

java - 是否有任何现成的 Java 库可用于通过 TCP 传输图像?

c# - 捕获 WebService 抛出的 SoapException

c# - 为 TrimEnd 和 TrimStart 创建一个字符数组

c# - 对于 jpg 图像文件,获得 3-4 种平均主色

android - 当 adb 通过 tcpip 连接时重新启动设备

WCF 服务使用被动发布的 SAML token