ASP.NET Web Interface: PushStreamContent compression is not flushed

I am using PushStreamContent

ASP.NET Web API to move events from server to client (using Server-Sent events). After every event dispatched, I call Flush

in Stream

to send the buffer data to the client. However, I noticed that flushing is not always (always). Sometimes some of the data is sent to the client, and the rest is sent when the next event is recorded (which might happen after a few seconds).

Here's some sample code:

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

      

How do I disable data buffering or force data flushing?

+4


source to share


3 answers


I start work.

In my case, the buffering was isssue. I had to



1) disable gzip for my answers <urlCompression doStaticCompression="true" doDynamicCompression="false" />

2) Make sure Prod proxy (Nginx) is not buffering either

+1


source


The source of the problem is stream cleaning.

In the sample code, you deform the original stream with a StreamWriter and then clean up the StreamWriter.



You also need to clean up the original stream:

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

      

0


source


After spending a full day figuring out what the problem was and HttpSelfHostServer

before (desperately) giving out the award, I found that the problem was with what I was using HttpSelfHostServer

and HttpSelfHostServer

needed to be tuned TransferMode = TransferMode.Streamed

to HttpSelfHostConfiguration

. All this.

0


source







All Articles