9

PushStreamContentサーバーからクライアントにイベントをプッシュするために ASP.NET Web API を使用しています (Server-Sent Events を使用)。イベントを送信するたびに、 を呼び出しFlushStream、バッファリングされたデータをクライアントにプッシュします。ただし、フラッシングが(常に)発生しないことに気付きました。場合によっては、データの一部がクライアントに送信され、残りは次のイベントが書き込まれたときに送信されます (数秒後に発生する可能性があります)。

コードサンプルは次のとおりです。

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

データのバッファリングを無効にしたり、データのフラッシュを強制するにはどうすればよいですか?

4

3 に答える 3

1

問題の原因は、ストリームがフラッシュされていることです。

コード サンプルでは、​​元のストリームを 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));
    }
  }
}
于 2015-07-20T15:24:01.697 に答える