Zack Weiner
Zack Weiner

Reputation: 674

Reading the content of HTTP Stream before the Content stream is Complete Windows Phone 8

I am trying to get a reference to a response stream before its complete in windows phone 8.

In other .Net platforms you can do

HttpWebRequest httpRequest = (HttpWebRequest)WebRequest.Create(myUri);
WebResponse subscribeWebResponse = null;
Stream subscribeStream = null;

subscribeWebResponse = httpRequest.GetResponse();
subscribeStream = subscribeWebResponse.GetResponseStream();

For the purpose of creating Portable class libraries I've used the HttpClientLibrary from nuget.

This Adds ref to extensions assembly Microsoft.Net.Http

this allows me to return the async request at the time the headers have been read instead of waiting for the content transfer to be complete with

var clientResponse = await httpClient.SendAsync(requestmessage, HttpCompletionOption.ResponseHeadersRead);

The problem I'm having is that in windows phone 8 it doesn't work correctly, and still awaits the completion of the content stream to return.

Additionally

await httpWebRequest.BeginGetResponse(callback, request) 

has the same behavior as these async methods are actually waiting for the completion of the web's response to continue execution.

So, is there any way to achieve the returning the response/stream at the point that i have received the response headers without Microsoft.Http.Net package? Even if it has to be a Windows Phone 8 Platform Specific Solution? Possibly an extension of HttpWebRequest?

Upvotes: 1

Views: 1105

Answers (2)

Darrel Miller
Darrel Miller

Reputation: 142094

From what I can tell, ResponseHeadersRead works on the WP8 emulator as it does on the desktop.

I installed the Win8 SDK. Created a windows phone app. I added this code to the MainPage ctor. This demonstrates a very rudimentary long polling example.

      var client = new HttpClient();

        var request = new HttpRequestMessage()
        {
            RequestUri = new Uri("http://oak:1001/longpolling")
        };
        client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, new CancellationToken())
            .ContinueWith((t) =>
            {
                var response = t.Result;
                response.Content.ReadAsStreamAsync()
                    .ContinueWith(s =>
                    {
                        var st = s.Result;
                        while (true)
                        {
                            var message= ReadNextMessage(st);
                        }
                    });       
            });
  }
   private static string ReadNextMessage(Stream stream)
        {
            int chr = 0;
            string output = "";
            while (chr != 10)
            {
                chr = stream.ReadByte();
                output += Convert.ToChar(chr);
            }
            return output;
   }

On my host dev machine I have a web api with a controller that looks like this...

public class LongPollingController : ApiController
    {
        public HttpResponseMessage Get()

        {
            Thread.Sleep(2000);
            var content = new PushStreamContent( (s,c,t) =>
            {
                int i = 0;
                while (true)
                {
                    try
                    {
                        var message = String.Format("The current count is {0} " + Environment.NewLine, i++);
                        var buffer = Encoding.UTF8.GetBytes(message);
                        s.Write(buffer, 0, buffer.Length);
                    }
                    catch (IOException exception)
                    {
                        s.Close();
                        return;
                    }
                    Thread.Sleep(1000);
                }
            });
            return new HttpResponseMessage(HttpStatusCode.OK)
            {
                RequestMessage = Request,
                Content = content
            };
        }
    }

Upvotes: 1

Robert McLaws
Robert McLaws

Reputation: 2592

So here's the deal. I would say that what you want to do is not possible, due to platform limitations... But SignalR has a WP client and is able to manage it. So it seems to me you have two options:

1) Dig into the SignalR source code to see how they do it (I'm on my phone right now so I can't provide a link).

UPDATE: Here is the link. They do some pretty neat tricks, like setting the Timeout to -1 for long-running clients. I think you should definitely use the techniques here.

OR

2) You can move whatever you're doing over to SignalR, which would gain the benefit of having a robust infrastructure and being cross-platform compatible.

HTH

Upvotes: 0

Related Questions