2013-07-25 8 views
6

私はMVCプロジェクトを持っています。このMVCプロジェクトには、コンテンツをクライアントにストリーミングする必要があるコントローラが1つ含まれています。ストリーミングが開始されると、コンテンツの長さを決定する方法はありません(オンザフライで計算されます)。だから私は(私はすでにバッファされた出力を無効にして、適切なHTTPヘッダを添付しました)定期HttpContext.Current.Response.OutputStreamを開き、書き始めるとフラッシング:チャンクコンテンツを返すMVCコントローラ

while (some condition){ 

    HttpContext.Current.Response.OutputStream.Write(buffer, 0, buffer.Length); 
    HttpContext.Current.Response.Flush(); 
} 

私はその後、閉じるためにストリームを強制する場合:

HttpContext.Current.Response.Close(); 

それは適切に(それがクライアントにEOFを示すために、最後に長さ0のチャンクを追加しません)チャンクされたコンテンツを終了していません。

私が代わりに、より優雅に出力ストリームを閉じた場合:

HttpContext.Current.Response.End(); 

OR

HttpContext.Current.ApplicationInstance.CompleteRequest(); 

をそれが正しくストリーム(最後に追加長さゼロのチャンク)を閉じますが、私は例外がによってスローされますこのアプリケーションは、ストリームがすでに書き込まれているため、HTTPヘッダーを出力ストリームに挿入できないことを示しています。

どちらの場合も、コントローラはnullを返します(またはEmptyActionResult)。

MVCスタックは、コントローラの実行が終了した後、すべてのActionResultがHTTPヘッダーを設定する必要があるため、例外が発生していると想定します。この場合、MVCでチャンクストリームをどのように実装しますか?

ありがとうございます!

EDIT:正確な例外がスローされるのである:

Uncaught Exception: System.Web.HttpException (0x80004005): Server cannot set status after HTTP headers have been sent. 
    at System.Web.Http.WebHost.HttpControllerHandler.EndProcessRequest(IAsyncResult result) 
    at System.Web.Http.WebHost.HttpControllerHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult result) 
    at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() 
    at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) 

答えて

2

私は解決策を見つけました。

エンコーディングが0の長さのチャンクで閉じなければならないチャンクHTTP 1.1標準指定は、要求モードがキープアライブ

キープアライブモードにある場合にのみ、クライアント/サーバ間の接続は、複数のために保持され要求/応答。先の応答がいつ終了するかをクライアントが知る他の方法がないので、チャンク符号化は、この文脈でゼロ長さのチャンクで終了する必要があります。

"Connection:keep-alive"ではなく、 "Connection:close"をヘッダーとして指定すると、要求の間に接続が維持されず、クライアントは応答終了の表示として接続を閉じることができます。 EOFを示す0の長さのチャンクを必要としない。

私は手動で使用してのHttpResponseを閉鎖することを決定した:以前接続がEOF時に終了しますクライアントに伝えるために、コードで指定したものの

HttpContext.Current.Response.Close(); 

を。これは、クライアントが0の長さのチャンクを受け取らなかったという問題を解決しました。なぜなら、クライアントはそれを要求しないからです。

関連する問題