2013-07-01 51 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信息。

相關問題