SignalR с сжатием gzip

возникли проблемы с разработкой клиента SignalR для концентратора, размещенного в asp.net веб-сайт с включенным сжатием gzip. Поскольку мы используем сжатие IIS, ответ от SignalR также сжимается, но клиент не понимает ответ, и мы получаем ошибку синтаксического анализа Json на стороне клиента.

SignalR внутренне использует HttpWebRequest чтобы сделать запросы http и HttpWebRequest можно настроить для автоматической распаковки ответа с помощью AutomaticDecompression собственность. Итак, если каким-то образом я могу достать HttpWebRequest объект, используемый SignalR для запроса, я должен иметь возможность установить автоматическую декомпрессию enable.

я думал, что смогу получить доступ к HttpWebRequest на предоставление HubConnection.Start С моей пользовательской реализации IHttpClient, IHttpClient.GetAsync принимает prepareRequest действие, которое, как я думал, должно дать мне доступ к HttpWebRequest, но, HttpHelper.GetAsync обертывания HttpWebRequest С HttpWebRequestWrapper до prepareRequest и HttpWebRequestWrapper не предоставляет доступ к HttpWebRequest.

HttpHelper класс является внутренним, поэтому не может его использовать, поэтому я не совсем уверен, как включить автоматическую декомпрессию с SignalR.

я могу подвергнуть HttpWebRequest на HttpWebRequestWrapper, но предпочел бы более простое решение, если оно существует. Есть идеи?

я использую 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;
        });

    }
....
}

1 ответов


насколько мне известно, кодировка и потоковая передача GZip не смешиваются. В случае транспорта forever frame клиент не сможет декодировать содержимое потоковой передачи, пока не будет получен весь ответ или, по крайней мере, значительный блок данных (из-за способа декодирования данных). В случае веб-сокетов в настоящее время нет поддержки кодирования любого рода, хотя, по-видимому, существует расширение спецификации для кодирования каждого сообщения будучи работал на.

тем не менее, если вы хотите попытаться обеспечить поддержку для LongPolling транспорта, единственный способ, я вижу, что это возможно, чтобы обеспечить свой собственный SignalR IHttpClient реализация. Вы можете видеть прямо сейчас, что DefaultHttpClient класс использует HttpHelper::GetAsync создает HttpWebRequest внутренне, и вы никогда не сможете получить доступ к этому, потому что у вас есть только доступ к IRequest что это HttpWebRequestWrapper в этой точке.

создав свой собственный IHttpClient вы можете возьмите на себя начальный экземпляр HttpWebRequest, выберите AutomaticDecompression а затем заверните это сами с HttpWebRequestWrapper.