TL; DR:如何流使用WCF已知大小的大文件,還是出現進展(Content-Length
)到最終用戶(網頁瀏覽器)?Transfering大文件:合併流傳輸和內容長度
我有一個WCF REST服務,下載,然後非常大的文件(1-20Gb)用於Web瀏覽器。爲了簡化,請將我的服務視爲代理。這迫使我在綁定上設置TransferMode = Streamed
或TransferMode = StreamedResponse
,或者在實際下載開始之前,最終客戶端將不得不等待源文件下載到網絡服務器。此外,緩衝傳輸模式會導致服務器死機(RAM使用率)。中級磁盤存儲不是一個選項。從TransferMode手冊頁:
(...)緩衝傳輸的內存緩衝區存放整個消息,直到 傳輸完成。
但設置TransferMode
到Streamed
或StreamedResponse
時,WCF不再返回頭Content-length
到客戶端,和一個新的頭Transfer-Encoding: chunked
添加。這是符合wikipedias article上分塊傳輸:
(...)使用傳輸編碼HTTP標頭中的Content-Length頭 (...)
的地方但我總是知道事先要傳輸的數據的大小,對於最終用戶來說,不知道下載的大小是非常令人沮喪的。所以:
(如何)我可以配置WCF綁定使用「流」傳輸模式(更具體地說,不緩衝整個郵件發送前),仍然使用Content-Length
頭?
一些線索:
This q/a指出HTTP標準不允許在同一消息中都
Transfer-Encoding
和Content-length: 123456
,所以我想這是不是一種選擇?我曾嘗試在IDispatchMessage.BeforeSendReply,但在這一點上
Content-Length
頭還沒有被刪除修改使用的檢查頭,並Transfer-Encoding
尚未確定,所以它是「太早」。我後來讀到了分塊傳輸編碼是在TCP層面上的,所以在這一點上改變標題可能不會工作,即使我可以。我試過設置aspNetCompatibilityEnabled
="true"
,將wcf傳輸模式設置爲緩衝輸出(默認),然後設置System.Web.HttpContext.Current.Response.BufferOutput = false;
。 wcf忽略了這個消息,但是這個消息被明確地緩衝了。這似乎是缺少功能,根據this link。但是在某個地方可能還有一個古怪的解決方法。
不幸的是,在這個問題說(我會有點強調這使得它更清楚),客戶端是Web瀏覽器。因此,客戶端的任何解決方法都必須使用JavaScript或任何其他瀏覽器可用的技巧。雖然如果有人對我的問題回答「不」,我可能不得不考慮自定義下載器,這可能看起來像您的答案。 – Tewr