在内容流完成Windows Phone 8之前读取HTTP流的内容

时间:2014-01-30 23:34:45

标签: windows-phone-8 httpwebrequest async-await dotnet-httpclient

我试图在Windows Phone 8中完成之前获得对响应流的引用。

在其他.Net平台上,您可以

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

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

为了创建可移植类库,我使用了nuget的HttpClientLibrary。

这将添加引用扩展程序集Microsoft.Net.Http

这允许我在读取标题时返回异步请求,而不是等待内容传输完成

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

我遇到的问题是,在Windows Phone 8中它无法正常工作,仍然等待内容流的完成才能返回。

此外

await httpWebRequest.BeginGetResponse(callback, request) 

具有与这些异步方法实际等待完成Web响应以继续执行的行为相同的行为。

那么,有没有办法实现在没有Microsoft.Http.Net包的情况下收到响应头时返回响应/流? 即使它必须是Windows Phone 8平台特定解决方案? 可能是HttpWebRequest的扩展?

2 个答案:

答案 0 :(得分:1)

据我所知,ResponseHeadersRead可以像在桌面上一样在WP8模拟器上运行。

我安装了Win8 SDK。创建了一个Windows手机应用程序。我将此代码添加到MainPage ctor。这表明了一个非常基本的长期民意调查示例。

      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;
   }

在我的主机开发机器上,我有一个带有控制器的web api,看起来像这样......

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
            };
        }
    }

答案 1 :(得分:0)

所以这是交易。我想说,由于平台的限制,你想做的事情是不可能的......但是SignalR有一个WP客户端并能够管理它。所以在我看来你有两个选择:

1)深入了解SignalR源代码,了解他们是如何做到的(我现在正在通电话,所以无法提供链接)。

更新: Here is the link。他们做了一些非常巧妙的技巧,比如为长期运行的客户端设置Timeout为-1。我认为你绝对应该使用这些技术。

OR

2)您可以将您正在做的任何事情转移到SignalR,这将获得具有强大基础设施和跨平台兼容的好处。

HTH