【问题标题】:ASP.NET Web API: PushStreamContent flush does not flushASP.NET Web API:PushStreamContent 刷新不刷新
【发布时间】:2015-04-22 09:32:01
【问题描述】:

我在 ASP.NET Web API 中使用PushStreamContent 将事件从服务器推送到客户端(使用服务器发送事件)。每次发送事件后,我在Stream 上调用Flush 将缓冲的数据推送到客户端。但是,我注意到冲洗不会(总是)发生。有时,部分数据会发送到客户端,其余的会在写入下一个事件时发送(可能会在几秒钟后发生)。

这是一个代码示例:

public class MyController : ApiController
{
  private static readonly string[] LineSeparators 
    = new[] { Environment.NewLine };

  public HttpResponseMessage GetData(string id)
  {
    var response = Request.CreateResponse();
    response.Content = new PushStreamContent(
      new Func<Stream, HttpContent, TransportContext, Task>(StartStream),
      new MediaTypeHeaderValue("text/event-stream") { CharSet = "UTF-8" });
    return response;
  }

  private async Task StartStream(Stream outputStream, HttpContent content, TransportContext context)
  {
    using (outputStream)
    using (var writer = new StreamWriter(outputStream, new UTF8Encoding(false)))
    {
      writer.NewLine = "\n";
      while (true)
      {
        WriteEvent(writer, "ping", DateTime.UtcNow.ToString("yyyy-MM-dd HH:mm:ss.fff", CultureInfo.InvariantCulture));
        await Task.Delay(TimeSpan.FromSeconds(1));
      }
    }
  }

  private static void WriteEvent(TextWriter writer, string eventType, string data)
  {
    writer.WriteLine("event:" + eventType);
    writer.WriteLine("data:" + data);
    writer.WriteLine();
    writer.Flush(); // StreamWriter.Flush calls Flush on underlying Stream
  }
}

如何禁用数据缓冲或强制刷新数据?

【问题讨论】:

  • 你找到解决办法了吗?
  • 不,很遗憾没有。

标签: c# asp.net-web-api server-sent-events pushstreamcontent


【解决方案1】:

我搞定了。

就我而言,缓冲是个问题。我不得不

1) 为我的回复禁用 gzip &lt;urlCompression doStaticCompression="true" doDynamicCompression="false" /&gt;

2) 确保 Prod (Nginx) 上的代理也没有缓冲

【讨论】:

  • 设置 web.config 值对我有用。
  • 我有同样的问题,但我使用的是HttpSelfHostServer(我在 Windows 服务中使用它),所以我无法控制那里的压缩(我认为它甚至没有启用默认情况下)。仍然 - 问题仍然存在:writer.Flush() 没有效果。如果我使用writer.close(),它会发送消息,但会关闭它并导致错误。有人解决过这个问题吗?
【解决方案2】:

问题的根源是正在刷新的 Stream。

在您的代码示例中,您使用 StreamWriter 扭曲原始流,然后刷新 StreamWriter。

您还需要刷新原始流:

private async Task StartStream(Stream outputStream, HttpContent content, TransportContext context)
{
  using (outputStream)
  using (var writer = new StreamWriter(outputStream, new UTF8Encoding(false)))
  {
    writer.NewLine = "\n";
    while (true)
    {
      WriteEvent(writer, "ping", DateTime.UtcNow.ToString("yyyy-MM-dd HH:mm:ss.fff", CultureInfo.InvariantCulture));
outputStream.Flush();
      await Task.Delay(TimeSpan.FromSeconds(1));
    }
  }
}

【讨论】:

    【解决方案3】:

    花了一整天的时间试图找出问题所在,并(拼命地)给予赏金之后,我发现问题在于我使用的是HttpSelfHostServer,并且需要在HttpSelfHostConfiguration 上配置TransferMode = TransferMode.Streamed。就是这样。

    【讨论】:

    • 或者,也可以使用 OWIN 自托管,因为它开箱即用
    猜你喜欢
    • 1970-01-01
    • 2011-04-13
    • 2012-02-22
    • 2011-01-16
    • 2020-11-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多