2013-07-01 52 views
2

我正在使用WCF流式传输将文件从WCF客户端传输到netTcpBinding服务。WCF:通过TransferMode传输文件到服务器时延迟的客户端响应=使用netTcpBinding流式传输

一旦客户端使用Stream实例调用服务,服务将开始通过套接字连接(StreamConnection)从Stream实例读取。但是,如果在服务端从流读取的过程中发生异常,客户端不能立即得到异常。

我发现了与绑定的sendTimeout相关的延迟时间。如果我设置sendTimeout=20 seconds,则客户端在20秒内得到异常延迟;如果sendTimeout = 1 second,客户端立即得到异常。

我做了一些研究。我的理解是,即使在服务上抛出异常,它也不会抛出客户端,直到StreamConnection.Read()/StreamConnection.Write()。这个超时时间看起来与绑定sendTimeout同步。

是否可以保留sendTimeout并让客户立即得到异常?

这里是服务绑定,(为了与大尺寸的传输文件,我改变maxReceivedMessageSize,,SendTimeOut和receiveTimeout等价值)

<netTcpBinding> 
    <binding name="StreamingNetTCPBinding" transferMode="Streamed" maxConnections="500" maxReceivedMessageSize="2147483647" maxBufferSize="2147483647" sendTimeout="00:45:00" receiveTimeout="23:00:00" listenBacklog="20"> 
     <readerQuotas maxArrayLength="2147483647" maxDepth="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" maxStringContentLength="2147483647" /> 
    </binding> 
    </netTcpBinding> 
+0

任何机构有任何想法? – user1256475

回答

0

您所看到的行为是由于与缓冲区相比,流模式的语义。当使用缓冲连接时,即使在使用请求/回复时,它实际上也是一个双工连接。一个待处理的接收总是被发布来接受传入的请求或回复任何未完成的请求。这就是为什么您可以通过单个通道从多个线程在单个NetTcp连接上发送多个未完成的请求。在流模式下,当发出请求时,呼叫实例将拥有该通道,直到呼叫完成。请求流被发送,并且只有在它被发送之后,我们才会发送连接上的接收/读取。这是因为如果请求消息没有完全发送,即使响应消息是Fault消息,也不能回复请求消息。

根据您的要求,您有几个选项可以解决这个问题,其中大部分选项只需要在服务代码中进行更改。在服务方面,如果抛出了异常,则需要捕获异常,排除传入流,然后重新抛出将导致返回故障消息的异常。当响应流被完全读取时,客户端已经完成了它正在发送的所有内容,现在正在等待响应。这确实要求发送整个请求流,并且在较大的请求失败的情况下,这可能是不希望的。如果不希望花费时间/带宽来接收剩余的消息,则可以在服务端对通道进行故障排除(使用Abort())。这将导致套接字断开连接,并且您将在客户端获得CommunicationException。这有一个缺点,就是没有收到有关哪里出错的信息,但会很快。

需要在客户端和服务器端进行更改的另一个选项是使用两个通道,并使用第二个通道接收有关第一个通道上的请求状态的OOB信息。

相关问题