KeepAlive与WCF和TCP?

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

receiveTimeout设置为无限,永不丢弃由于不活动而导致的连接。 但从我的理解,无论如何都可以删除连接,所以我创建了一个简单的双向keepalive服务方法,客户端每9分钟调用一次以保持连接活动。 连接永远不会中断是非常重要的。

这是正确的方法吗? 或者我可以简单地删除我的保持,因为receiveTimout设置为无限?

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

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

首先,“无限”是一种半有效值。 有两个特殊的配置序列化器将“无限”转换为TimeSpan.MaxValueint.MaxValue (所以它们实际上并不是“无限”),但WCF中的所有内容似乎都没有认识到这一点。 因此,最好使用时间值明确指定超时。

其次,您的服务中不需要“keepalive”方法,因为WCF提供了所谓的“可靠会话”。 如果你添加那么WCF将通过“基础设施消息”提供它自己的保持活动机制。

通过拥有自己的“keepalive”机制,您可以有效地将服务负担加倍,实际上您可以创建比解决的问题更多的问题。

第三,使用可靠会话时,使用reliableSession的inactivityTimeout设置。 这样做有两件事。 首先,它控制基础架构(keepalive)消息的发送频率。 它们以超时值的一半发送,因此如果将其设置为18分钟,则它们将每9分钟发送一次。 其次,如果在非活动超时内没有收到任何基础设施或操作消息(即作为数据合同一部分的消息),则连接将中止,因为可能存在问题(一方已崩溃,存在网络问题等。 )。

receiveTimeout是在连接中止之前不能接收任何操作消息的最长时间(默认值为10分钟)。 将此值设置为较大的值( Int32.MaxValue在24天附近的某处)可以保持连接的连接,将inactivityTimeout设置为较小的值(同样,默认值为10分钟)(到小于2x的时间)网络路由器从不活动状态断开连接之前的最长时间)保持连接活动。

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

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

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

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

另请参见: 如何正确配置WCF NetTcp双工可靠会话?

根据我的经验,我发现问题不一定是由WCF服务或配置引起的,而是客户端自己的路由器。

以前我遇到了设置长时间超时并且在一段时间不活动后连接仍然丢失的问题。 我相信一些路由器有一个机制来丢弃它认为不再活动的连接,所以我唯一的解决方案是在服务上实现一个空方法并定期从客户端调用它。