Wednesday, September 17, 2008

Creating an HTTP Streaming Client in Silverlight

I read and played with WebClient and HttpWebRequest classes. Both of these classes allow you to make requests to an http server. Once you make the request, you give a callback that is invoked once the response is received so you can happily examine the response. Let's say your HTTP server is streaming a file, or it wants to hold on to your request and sends messages as necessary from the same connection. To be able to work with such a server, your http client must be able to read the data as soon as it is available without requiring the response to be received completely. 

After searching silverlight forums I found a solution. The solution assumes that you have a control on the server code or the response you are getting is bigger than 4KB (IE buffers upto 4KB).

Here is the code snipped for your client side:

HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
request.Method = "POST";
request.AllowReadStreamBuffering = false;
try
{
 request.BeginGetResponse(OnResponseReady, request);
}
catch (Exception excp)
{
 System.Diagnostics.Debugger.Break();
}


....


void OnResponseReady(IAsyncResult result)
{
 HttpWebResponse response = request.EndGetResponse(result) as HttpWebResponse;
 Stream stream = response.GetResponseStream();

 string responseText = null;
 using (StreamReader sr = new StreamReader(stream))
 {
  char[] buffer = new Char[256];
  int nByte = sr.Read(buffer, 0, buffer.Length);
  while (nByte > 0)
  {
   responseText = new String(buffer, 0, nByte);
//read next piece
        nByte = sr.Read(buffer, 0, buffer.Length);                    
  }
 }                
}

Note that I do not call sr.ReadToEnd. If I do that then it blocks on this call until the whole response is received.


The response is buffered in IE until it is bigger than 4KB. Therefore, if you have access to the server code then you need to change it to send 4KB garbage data before it starts sending meaningful stuff. If you do not have access to the server code then your code will be able to access streamign data only if it is bigger than 4KB.

This is such a fundamental and hidden feature. I want people to know and use it so we can all start finding other gotcha's if there are any more.
 

1 comment:

Joel Thoms said...

Hey! I have been looking for a solution for this problem for DAYS. I tried WebClient, HttpWebRequest and Sockets!

I wasn't aware of the mandatory 4k buffering by IE. What a PAIN this was. Thanks for the help!

Have you done any additional work or updates to get around the 4k buffer?