Signalr 具有gzip压缩的信号器

Signalr 具有gzip压缩的信号器,signalr,Signalr,在为asp.net网站中承载的集线器开发启用gzip压缩的信号器客户端时遇到问题。由于我们使用的是IIS压缩,来自SignalR的响应也会被压缩,但是,客户端不理解该响应,因此在客户端会出现Json解析错误 SignalR内部使用HttpWebRequest发出http请求,并且HttpWebRequest可以配置为使用AutomaticDecompression属性自动解压缩响应。因此,如果我能够以某种方式获得signar用于发出请求的HttpWebRequest对象,我应该能够设置enabl

在为asp.net网站中承载的集线器开发启用gzip压缩的信号器客户端时遇到问题。由于我们使用的是IIS压缩,来自SignalR的响应也会被压缩,但是,客户端不理解该响应,因此在客户端会出现Json解析错误

SignalR内部使用
HttpWebRequest
发出http请求,并且
HttpWebRequest
可以配置为使用
AutomaticDecompression
属性自动解压缩响应。因此,如果我能够以某种方式获得signar用于发出请求的
HttpWebRequest
对象,我应该能够设置enable automatic decompression

我想我应该能够通过提供
HubConnection来访问
HttpWebRequest
。从我的
ihttppclient
ihttppclient的自定义实现开始,
GetAsync
采取
prepareRequest
操作,我认为这应该让我能够访问
HttpWebRequest
,但是,
HttpHelper.GetAsync
在传递到
prepareRequest
之前用
HttpWebRequestWrapper
包装
HttpWebRequestWrapper
,并且
HttpWebRequestWrapper
不提供对
HttpWebRequest
的访问

HttpHelper
类是内部类,因此无法使用它,因此,我不确定如何使用signar启用自动解压缩

我可以在
HttpWebRequestWrapper
中公开
HttpWebRequest
,但是,如果存在更简单的解决方案,我会更喜欢。有什么想法吗

我使用的是信号器版本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;
        });

    }
....
}
具有自动解压缩功能的公共类HttpClient:IHttpClient
{
只读DefaultHttpClient _httpClient=新的DefaultHttpClient();
私有只读解压缩方法\u解压缩方法;
具有自动解压缩功能的公共HttpClientWithAutoDecompression(解压缩方法DecompressionMethods)
{
_减压方法=减压方法;
}
公共任务GetAsync(字符串url,操作准备请求)
{
Task Task=\u httpClient.GetAsync(url,
请求=>
{
[错误:请求实际上是HttpRequestWrapper,并且
不公开HttpWebRequest]**]
var httpWebRequest=(httpWebRequest)请求;
httpWebRequest.AutomaticDecompression=\u解压缩方法;
准备请求(请求);
});
返回任务。继续(响应=>
{
Debug(这是“Response:{0}”,Response.Result.ReadAsString());
返回响应。结果;
});
}
....
}

就我所知,GZip编码和流式传输不能混用。在永久帧传输的情况下,在接收到整个响应或至少一个重要的数据块之前(由于数据解码的方式),客户端将无法解码流媒体内容上的任何内容。对于web套接字,目前不支持任何类型的编码,尽管每个消息编码的规范显然有一个扩展

也就是说,如果您想尝试提供对LongPolling传输的支持,我认为唯一可行的方法就是提供您自己的SignalR
IHttpClient
实现。您现在可以看到,
DefaultHttpClient
类使用了
HttpHelper::GetAsync
,它在内部创建了
HttpWebRequest
,而您永远也无法得到它,因为此时您只能访问
IRequest
,它是
HttpWebRequestWrapper


通过创建自己的
IHttpClient
,您可以接管
HttpWebRequest
的初始实例化,设置
自动压缩
,然后使用
HttpWebRequestWrapper

将其包装起来,但它应该与长轮询传输一起工作,当长时间运行的请求在向客户端返回消息时完成,或者我遗漏了什么?谢谢huys,我理解为什么压缩不能与流一起工作,我认为我的主要问题是SingnalR Api接口不允许您访问它用于发出请求的HttpWebRequest,基本上,我想更新
httpWebRequest.AutomaticDecompression
属性,但是signer将“httpWebRequest”包装在一个不公开AutomaticDecompression属性的包装器中。dfowler建议我修改包装器类并重建信号器。现在我只是使用反射来访问我需要访问的私有财产。@akoeplinger是的,它应该与LP transport一起工作。当然,这是使用效率方面最差的传输方式,因此它可能会否定gzip的任何潜在好处,除非您的消息有效负载碰巧很大。谢谢Drew,请注意:您可以创建自己的IHttpClient,但您也必须实现自己的HttpHelper::GetAsync,因为HttpHelper是内部的,因此,您不能在程序集中使用它。因此,我在DefaultHttpClient上创建了一个包装器,并使用反射来访问_请求。FieldInfo requestField=typeof(HttpWebRequestWrapper.GetField(“_请求”,BindingFlags.Instance | BindingFlags.NonPublic);var httpWebRequest=(httpWebRequest)requestField.GetValue(request);httpWebRequest.AutomaticDecompression=DecompressionMethods.GZip | DecompressionMethods.Deflate@FaisalMansoor您不需要HttpHelper,这只是SignalR的内部实现细节。如果愿意,您可以在IHttpClient中直接内联执行自己的HttpWebRequest实例化。至于反思。。。。无可奉告PI现在检查了一个同时启用了gzip压缩的服务器,发现signar.Client没有通过发送接受编码:gzip