Having some problem developing a SignalR client for a Hub hosted in asp.net website with gzip compression enabled. Since we are using IIS compression, the response from SignalR also gets compressed, but, the client does not understand the response and we get a Json parsing error on the client side.
SignalR internally uses HttpWebRequest
to make make http requests and HttpWebRequest
can be configured to automatically decompress the response using AutomaticDecompression
property. So, if somehow I can get hold of the HttpWebRequest
object used by SignalR to make the request, I should be able to set the enable automatic decompression.
I thought I should be able to get access to the HttpWebRequest
by providing HubConnection.Start
with my custom implementation of IHttpClient
, IHttpClient.GetAsync
takes a prepareRequest
action which I thought should give me access to the HttpWebRequest
, but, HttpHelper.GetAsync
wraps the HttpWebRequest
with HttpWebRequestWrapper
before passing to prepareRequest
and HttpWebRequestWrapper
does not provide access to HttpWebRequest
.
HttpHelper
class is internal so can't use it as well, so, I am not exactly sure how to enable automatic decompression with SignalR.
I can expose the HttpWebRequest
in HttpWebRequestWrapper
, but, would prefer a simpler solution if one exists. Any thougths?
I am using SignalR version 0.5.1.10822
My auto decompression 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;
});
}
....
}
To the best of my knowledge GZip encoding and streaming do not mix. In the case of the forever frame transport the client wouldn't be able to decode any on the streaming content until the entire response, or at least a significant block of data, is received (due to the way the data is decoded). In the case of web sockets there is not support for encoding of any kind at this time, although there is apparently an extension to the specification for per message encoding being worked on.
That said, if you wanted to attempt to provide support for the LongPolling transport, the only way I can see this being possible is to provide your own SignalR IHttpClient
implementation. You can see right now that the DefaultHttpClient
class uses HttpHelper::GetAsync
which creates the HttpWebRequest
internally and you can never get your hands on that because you only have access to the IRequest
which is HttpWebRequestWrapper
at that point.
By creating your own IHttpClient
you can take over the initial instantiation of the HttpWebRequest
, set the AutomaticDecompression
and then wrap that up yourself with the HttpWebRequestWrapper
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With