gpt4 book ai didi

c# - WCF:使用 TransferMode=Streamed over netTcpBinding 将文件传输到服务器时,对客户端的响应延迟

转载 作者:太空宇宙 更新时间:2023-11-03 16:11:08 27 4
gpt4 key购买 nike

我正在使用 WCF 流将文件从 WCF 客户端传输到 netTcpBinding 服务。

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

我发现延迟时间与绑定(bind)的sendTimeout有关。如果我设置 sendTimeout=20 seconds,客户端会在 20 秒延迟后得到异常;如果 sendTimeout = 1 second,客户端会立即收到异常。

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

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

这里是服务绑定(bind),(为了传输大文件,我改变了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>

最佳答案

您看到的行为是由于流模式与缓冲模式相比的语义。使用缓冲连接时,它下面实际上是一个双工连接,即使使用请求/回复也是如此。挂起的接收总是被发布以接受传入的请求或对任何未完成请求的回复。这就是为什么您可以通过单个 channel 从多个线程在单个 NetTcp 连接上发送多个未完成的请求。在流模式下,当发出请求时,调用的实例拥有 channel ,直到调用完成。请求流被发送,只有在它被发送后我们才会在连接上发出接收/读取。这是因为如果请求消息实际上尚未完全发送,即使响应消息是错误消息,您也无法回复请求消息。

根据您的要求,您有几个选项可以处理这个问题,其中大部分只需要更改您的服务代码。在服务端,如果抛出异常,则需要捕获异常,排空传入流,然后重新抛出异常,这将导致返回 Fault 消息。由于响应流已被完全读取,客户端已完成所有发送,现在正在等待响应。这确实需要发送整个请求流,并且在大型请求过早失败的情况下,这可能是不可取的。如果不希望花费时间/带宽来接收消息的其余部分,那么您可以在服务端对 channel 进行故障处理(使用 Abort())。这将导致套接字断开连接,您将在客户端收到 CommunicationException。这样做的缺点是无法收到有关出错信息的信息,但会非常即时。

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

关于c# - WCF:使用 TransferMode=Streamed over netTcpBinding 将文件传输到服务器时,对客户端的响应延迟,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17400589/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com