AspNetCore.Docs.Samples/fundamentals/streaming/SynchronousWithNewtonsoftJson/Results/SongLyricsResult.cs

69 lines
2.3 KiB
C#

namespace SynchronousWithNewtonsoftJson.Results;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using SynchronousWithNewtonsoftJson.Model;
public class SongLyricsResult : IActionResult
{
ILyricsSource _lyricsSource;
JsonSerializer _serializer;
public SongLyricsResult(ILyricsSource lyricsSource, JsonSerializer serializer)
{
_lyricsSource = lyricsSource;
_serializer = serializer;
}
static readonly byte[] JSONArrayStart = new byte[] { (byte)'[' };
static readonly byte[] JSONArraySeparator = new byte[] { (byte)',' };
public async Task ExecuteResultAsync(ActionContext context)
{
Console.WriteLine(
"[{0:yyyy-MM-dd HH:mm:ss}] Start streaming result to {1}",
DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"),
context.HttpContext.Connection.RemoteIpAddress);
var startTimeUTC = DateTime.UtcNow;
try
{
await context.HttpContext.Response.Body.WriteAsync(JSONArrayStart, context.HttpContext.RequestAborted);
while (true)
{
foreach (string line in _lyricsSource.GetSongLyrics())
{
using (var streamWriter = new StreamWriter(context.HttpContext.Response.Body))
using (var jsonWriter = new JsonTextWriter(streamWriter))
_serializer.Serialize(jsonWriter, line);
await context.HttpContext.Response.Body.WriteAsync(JSONArraySeparator, context.HttpContext.RequestAborted);
await context.HttpContext.Response.Body.FlushAsync(context.HttpContext.RequestAborted);
await Task.Delay(200);
}
}
// No JSONArrayEnd needs to be written, because the above loop will never exit.
}
catch (OperationCanceledException)
{
}
finally
{
var stopTimeUTC = DateTime.UtcNow;
var duration = stopTimeUTC - startTimeUTC;
Console.WriteLine(
"[{0:yyyy-MM-dd HH:mm:ss}] Stop streaming result to {1}, rickrolled for {2}",
DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"),
context.HttpContext.Connection.RemoteIpAddress,
duration);
}
}
}