57 lines
2.0 KiB
C#
57 lines
2.0 KiB
C#
namespace SynchronousWithNewtonsoftJson.Middleware;
|
|
|
|
using Microsoft.AspNetCore.Http;
|
|
using Newtonsoft.Json;
|
|
using SynchronousWithNewtonsoftJson.Model;
|
|
|
|
public class SongLyricsMiddleware
|
|
{
|
|
RequestDelegate _next;
|
|
ILyricsSource _lyricsSource;
|
|
JsonSerializer _serializer;
|
|
|
|
public SongLyricsMiddleware(RequestDelegate next, ILyricsSource lyricsSource, JsonSerializer serializer)
|
|
{
|
|
_next = next;
|
|
_lyricsSource = lyricsSource;
|
|
_serializer = serializer;
|
|
}
|
|
|
|
public Task InvokeAsync(HttpContext context)
|
|
{
|
|
if (!context.Request.Path.StartsWithSegments(new PathString("/middleware/sing")))
|
|
return _next(context);
|
|
else
|
|
return InvokeAsyncImplementation(context);
|
|
}
|
|
|
|
static readonly byte[] JSONArrayStart = new byte[] { (byte)'[' };
|
|
static readonly byte[] JSONArraySeparator = new byte[] { (byte)',' };
|
|
|
|
public async Task InvokeAsyncImplementation(HttpContext context)
|
|
{
|
|
await context.Response.Body.WriteAsync(JSONArrayStart, context.RequestAborted);
|
|
|
|
while (true)
|
|
{
|
|
foreach (string line in _lyricsSource.GetSongLyrics())
|
|
{
|
|
// Since we are performing our own writes outside of the JsonTextWriter, we need it to be logically
|
|
// set up and torn down for each object we output. Simply calling Flush() might work in practice but
|
|
// is assuming internal implementation details.
|
|
using (var streamWriter = new StreamWriter(context.Response.Body))
|
|
using (var jsonWriter = new JsonTextWriter(streamWriter))
|
|
_serializer.Serialize(jsonWriter, line);
|
|
|
|
await context.Response.Body.WriteAsync(JSONArraySeparator, context.RequestAborted);
|
|
|
|
await context.Response.Body.FlushAsync(context.RequestAborted);
|
|
|
|
await Task.Delay(200);
|
|
}
|
|
}
|
|
|
|
// No JSONArrayEnd needs to be written, because the above loop will never exit.
|
|
}
|
|
}
|