【问题标题】:Timeout on endless Http stream无限 Http 流超时
【发布时间】:2017-04-20 20:24:53
【问题描述】:

我正在为 REST 服务编写 C# 客户端以访问 Http 流 API。我应该打开流并接收服务器以无穷无尽的方式发送的消息。在从流中读取外部命令时应该停止。 HttpClient 用于实现。变量 streamingActive 用于停止从流中读取,因为 reader.EndOfStream 永远不会返回值 true。

using (HttpClient httpClient = new HttpClient())
{
    httpClient.Timeout = TimeSpan.FromMilliseconds(Timeout.Infinite);
    var messagesUri = "http://127.0.0.1:8080/api/messages/progress?sender_id=7837492342";
    var stream = httpClient.GetStreamAsync(messagesUri).Result;

    using (var reader = new StreamReader(stream))
    {
        while (streamingActive && !reader.EndOfStream)
        {
            var currentLine = reader.ReadLine();
            try
            {
                var psMessage = JsonConvert.DeserializeObject<PSMessage>(currentLine);
                Console.WriteLine(psMessage);
            }
            catch (JsonReaderException exc)
            {}
        }
    }
}

当有来自服务器的消息时,它工作正常。如果在大约 300 秒内没有来自服务器的新消息,则调用 reader.EndOfStream 抛出异常“操作已超时。”

at System.Net.ConnectStream.Read(Byte[] buffer, Int32 offset, Int32 size)
at System.Net.Http.HttpClientHandler.WebExceptionWrapperStream.Read(Byte[] buffer, Int32 offset, Int32 count)

有没有办法让流(假设)永远打开?

【问题讨论】:

    标签: c# timeout http-streaming


    【解决方案1】:

    如果你愿意放弃StreamReader,为什么不直接打开一个Stream对象呢?以下是通用应用程序(使用 Windows.Web API)

    HttpResponseMessage respMessage;
    //note: client and request is defined elsewhere.
    respMessage = client.SendRequestAsync(request, HttpCompletionOption.ResponseHeadersRead);
    using (var responseStream = await respMessage.Content.ReadAsInputStreamAsync())
    {
       using (var fileWriteStream = await fileToStore.OpenAsync(FileAccessMode.ReadWrite))
         {
            while (streamingActive && (await responseStream.ReadAsync(streamReadBuffer, bufferLength, InputStreamOptions.None)).Length > 0)
            {
              await fileWriteStream.WriteAsync(streamReadBuffer);
           }
         }
    }
    

    这应该无限期地等待await responseStream.ReadAsync。如果您仍然需要取消操作,您可以使用TaskCancellationToken 方法。

    【讨论】:

      猜你喜欢
      • 2011-03-22
      • 1970-01-01
      • 2017-07-20
      • 1970-01-01
      • 1970-01-01
      • 2015-11-26
      • 2015-11-22
      • 2021-01-08
      • 1970-01-01
      相关资源
      最近更新 更多