服务中断时,WCF客户端会忽略超时值

时间:2012-08-10 13:44:05

标签: .net vb.net wcf wcf-client

我有一个使用WCF的VB .NET应用程序。我已经为代码中的所有内容设置了客户端超时:

    Dim oMastSrv As MastSvc.IclsIOXferClient = Nothing

    Dim binding As New ServiceModel.NetTcpBinding("NetTcpBinding_IclsIOXfer")
    Dim intTimeout As Integer = 2500
    binding.SendTimeout = New TimeSpan(0, 0, 0, 0, intTimeout)
    binding.ReceiveTimeout = New TimeSpan(0, 0, 0, 0, intTimeout)
    binding.OpenTimeout = New TimeSpan(0, 0, 0, 0, intTimeout)
    binding.CloseTimeout = New TimeSpan(0, 0, 0, 0, intTimeout)
    Dim address As New ServiceModel.EndpointAddress("net.tcp://" & GetSrvIP(intSrvID) & ":30000/MyMastSvc")

    oMastSrv = New MastSvc.IclsIOXferClient(binding, address)
    Try
        oMastSrv.ServiceConnect( ... )
        oMastSrv.InnerChannel.OperationTimeout = New TimeSpan(0, 0, 0, 0, intTimeout)
    Catch ex As Exception
        ...
    End Try

当我连接到崩溃的服务时,Endpoint Not Found异常需要花费超过20秒而不是我指定的2.5。这实际上是我的负载平衡,我需要知道服务在2.5秒内消失了。有没有办法在所需的时间跨度内抛出此异常?

BTW,例外情况如下:

  

无法连接到net.tcp://192.168.227.130:30000 / MXIOXfer。该   连接尝试持续时间为00:00:02.4209684。 TCP   错误代码10060:连接尝试失败,因为已连接   一段时间后,党没有正确回应,或已确立   连接失败,因为连接的主机无法响应   192.168.227.130:30000。

但确实需要超过20秒。我已经打开了WCF跟踪并且可以在异常之前看到TCP操作失败警告并且它具有实时:

  

无法连接到net.tcp://192.168.227.130:30000 / MXIOXfer。该   连接尝试持续时间跨度为00:00:21.0314092。 TCP   错误代码10060:连接尝试失败,因为已连接   一段时间后,党没有正确回应,或已确立   连接失败,因为连接的主机无法响应   192.168.227.130:30000。

如果它有任何不同,服务的所有通信都在不同的线程上完成。

编辑:

This thread似乎表明套接字超时是由操作系统设置的。这样的事情是否有注册表设置?

2 个答案:

答案 0 :(得分:3)

结合在SO和MSDN中找到的详细信息我和eol引用的社交线程引导我进入这些注册表设置:

  

HKEY_LOCAL_MACHINE \ SYSTEM \ CURRENTCONTROLSET \服务\ TCPIP \参数\接口{XXXXXXXXXXXX-XXXX-XXXXXXXXXXXX} \ TcpInitialRTT

     

值类型:REG_DWORD-number

     

有效范围:0-0xFFFF

     

默认值:3秒

     

描述:该参数控制用于a的初始超时   TCP连接请求和初始数据重传   每个接口的基础。使用此参数进行调整时请小心   因为使用了指数退避。将此值设置为大于   3导致对不存在的地址的超时时间更长。

  

HKEY_LOCAL_MACHINE \ SYSTEM \ CURRENTCONTROLSET \服务\ TCPIP \参数\接口{XXXXXXXXXXXX-XXXX-XXXXXXXXXXXX} \ TcpMaxConnectRetransmissions

     

值类型:REG_DWORD-number

     

有效范围:0-255(十进制)

     

默认值:2

     

描述:该参数确定TCP的次数   在中止尝试之前重新发送连接请求(SYN)。该   每次连续重传,重传超时加倍   在给定的连接尝试中。初始超时由控制   TcpInitialRtt注册表值。

  

HKEY_LOCAL_MACHINE \ SYSTEM \ CURRENTCONTROLSET \服务\ TCPIP \参数\接口{XXXXXXXXXXXX-XXXX-XXXXXXXXXXXX} \ TcpMaxDataRetransmissions的

     

值类型:REG_DWORD-number

     

有效范围:0-0xFFFFFFFF

     

默认值:5

     

描述:该参数控制   TCP重新传输单个数据段的次数(不是   中止连接之前的连接请求段。该   每次连续重传,重传超时加倍   在连接上。响应恢复后重置。重传   使用历史记录动态调整超时(RTO)值   测量每个的往返时间(平滑往返时间,或SRTT)   连接。新连接上的启动RTO由   TcpInitialRtt注册表值。

由于每次重试失败的连接上的超时值都加倍,因此默认值使第一次尝试在3秒内失败,第二次失败在6中失败,第三次和最后一次尝试在12秒内失败,或总共21秒。顺便说一下, TcpMaxDataRetransmissions 密钥与此无关,我将其包含在内,以便完整性和后来的内容。

默认情况下,这些值都不存在,您必须添加它们才能更改它们。找出要执行此操作的接口很容易,每个接口都有一个包含其当前IP地址的密钥。 (甚至还有一个用于localhost。)在我自己的情况下,只需在VM接口上将 TcpMaxConnectRetransmissions 设置为零(0)即可将我的套接字超时默认为3秒,这足够接近2.5到工作。当WCF服务现在崩溃时,我的负载平衡工作。

答案 1 :(得分:1)

我相信这篇文章谈到同一个问题:wcf channelfactory and opentimeout

问题是底层套接字有一个默认的20s左右的超时,WCF没有覆盖。通过异步打开来检查最后一个答案,以获得实现自己的超时的方法。