Signalr 具有gzip压缩的信号器
在为asp.net网站中承载的集线器开发启用gzip压缩的信号器客户端时遇到问题。由于我们使用的是IIS压缩,来自SignalR的响应也会被压缩,但是,客户端不理解该响应,因此在客户端会出现Json解析错误 SignalR内部使用Signalr 具有gzip压缩的信号器,signalr,Signalr,在为asp.net网站中承载的集线器开发启用gzip压缩的信号器客户端时遇到问题。由于我们使用的是IIS压缩,来自SignalR的响应也会被压缩,但是,客户端不理解该响应,因此在客户端会出现Json解析错误 SignalR内部使用HttpWebRequest发出http请求,并且HttpWebRequest可以配置为使用AutomaticDecompression属性自动解压缩响应。因此,如果我能够以某种方式获得signar用于发出请求的HttpWebRequest对象,我应该能够设置enabl
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传输的支持,我认为唯一可行的方法就是提供您自己的SignalRIHttpClient
实现。您现在可以看到,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