2012-10-03 262 views
7

在啓用了gzip壓縮功能的asp.net網站中託管的Hub的開發SignalR客戶端時遇到了一些問題。由於我們使用IIS壓縮,SignalR的響應也會被壓縮,但客戶端並不理解響應,並且客戶端會收到Json解析錯誤。SignalR wth gzip壓縮

SignalR內部使用HttpWebRequest來使make http請求和HttpWebRequest可以配置爲使用AutomaticDecompression屬性自動解壓縮響應。所以,如果能以某種方式獲得SignalR使用的HttpWebRequest對象發出請求,我應該能夠設置啓用自動解壓縮。

,我想我應該能夠通過提供HubConnection.Start我的IHttpClient自定義實現來獲得訪問HttpWebRequestIHttpClient.GetAsync採取prepareRequest行動,我認爲應該給我訪問HttpWebRequest,但是,HttpHelper.GetAsyncHttpWebRequestHttpWebRequestWrapper包裝在傳遞到prepareRequestHttpWebRequestWrapper之前不提供對HttpWebRequest的訪問。

HttpHelper類是內部的所以不能用它爲好,所以,我不完全知道如何啓用自動解壓縮與SignalR。

我可以公開HttpWebRequestHttpWebRequestWrapper,但是,如果存在一個更喜歡更簡單的解決方案。你有什麼想法?

我使用SignalR版本0.5.1.10822

我自耦減壓的HttpClient:

public class HttpClientWithAutoDecompression : IHttpClient 
{ 
    readonly DefaultHttpClient _httpClient = new DefaultHttpClient(); 

    private readonly DecompressionMethods _decompressionMethods; 
    public HttpClientWithAutoDecompression(DecompressionMethods decompressionMethods) 
    { 
     _decompressionMethods = decompressionMethods; 
    } 

    public Task<IResponse> GetAsync(string url, Action<IRequest> prepareRequest) 
    { 
     Task<IResponse> task = _httpClient.GetAsync(url, 
      request => 
       { 
        [ERROR: request is actually HttpRequestWrapper and 
        does not expose HttpWebRequest]**    ] 
        var httpWebRequest = (HttpWebRequest) request; 
        httpWebRequest.AutomaticDecompression = _decompressionMethods; 
        prepareRequest(request); 
       }); 

     return task.ContinueWith(response => 
     { 
      Log.Debug(this, "Response: {0}", response.Result.ReadAsString()); 
      return response.Result; 
     }); 

    } 
.... 
} 
+0

現在我已經檢查了也啓用了gzip壓縮,並發現SignalR.Client不發送的Accept-Encoding的服務器上:在默認情況下的gzip,所以我的服務器未壓縮的消息作出響應,一切都按預期工作。看起來你的客戶端錯誤地發送了Accept-Encoding頭文件,或者你的服務器強制每一個對gzip的響應(內置IIS壓縮都沒有)。你可以檢查小提琴手是怎麼回事? –

回答

9

要盡我所知gzip編碼和流媒體的不要混用。在永遠幀傳輸的情況下,客戶端將無法解碼流內容上的任何內容,直到接收到整個響應或至少一個重要的數據塊(由於數據被解碼的方式)。在網絡套接字的情況下,目前不支持任何類型的編碼,儘管對於每個消息編碼being worked on的規範明顯有一個擴展。這就是說,如果你想試圖爲LongPolling傳輸提供支持,唯一可以看到這種情況的方法是提供你自己的SignalR IHttpClient實現。您可以立即將DefaultHttpClient類使用HttpHelper::GetAsync它創建HttpWebRequest內部,你永遠不能得到你的手,因爲你只能訪問到IRequest這是HttpWebRequestWrapper在這一點上看到的。

通過創建自己的IHttpClient你可以接管HttpWebRequest的初始實例,設置AutomaticDecompression,然後換行了自己與HttpWebRequestWrapper

+1

但它應該與longPolling傳輸一起工作,因爲當向客戶端返回消息時,長時間運行的請求會完成,或者我錯過了什麼? –

+0

感謝huys,我明白爲什麼壓縮不能用於流媒體,我認爲我的主要問題是SingnalR Api接口不允許你訪問它用來發出請求的HttpWebRequest,基本上我想更新' httpWebRequest.AutomaticDecompression'屬性,但是,SignalR將'httpWebRequest'封裝在一個不公開AutomaticDecompression屬性的包裝器中。 dfowler建議我修改包裝類並重建SignalR。現在我只是使用反射來訪問我需要訪問的私有屬性。 –

+0

@akoeplinger是的,它應該與LP運輸工作。當然這是使用效率最差的傳輸方式,所以它可能會否定gzip的任何潛在好處,除非您的消息有效載荷很大。 –