From 9cb5e882c7b8f40609e18f359baa70fcac2bf25a Mon Sep 17 00:00:00 2001 From: Mohammad Mahdi Date: Tue, 1 Apr 2025 13:49:46 +0330 Subject: [PATCH] Crude base implementation --- HoolIt.sln.DotSettings.user | 2 + HoolIt/Program.cs | 74 +++++++++++++++++++++------ HoolIt/Properties/launchSettings.json | 3 +- 3 files changed, 62 insertions(+), 17 deletions(-) create mode 100644 HoolIt.sln.DotSettings.user diff --git a/HoolIt.sln.DotSettings.user b/HoolIt.sln.DotSettings.user new file mode 100644 index 0000000..cfd23a5 --- /dev/null +++ b/HoolIt.sln.DotSettings.user @@ -0,0 +1,2 @@ + + ForceIncluded \ No newline at end of file diff --git a/HoolIt/Program.cs b/HoolIt/Program.cs index 26fa84d..28badf5 100644 --- a/HoolIt/Program.cs +++ b/HoolIt/Program.cs @@ -1,3 +1,5 @@ +using System.Collections.Concurrent; +using System.Text; using System.Text.Json.Serialization; var builder = WebApplication.CreateSlimBuilder(args); @@ -9,27 +11,69 @@ builder.Services.ConfigureHttpJsonOptions(options => var app = builder.Build(); -var sampleTodos = new Todo[] +var subscribers = new ConcurrentDictionary>(); + +// HAPI! +// https://github.com/jheising/HAPI +var createApi = app.MapGroup("/create/with"); +createApi.MapGet("/{feedId}", async (HttpContext context,string feedId) => { - new(1, "Walk the dog"), - new(2, "Do the dishes", DateOnly.FromDateTime(DateTime.Now)), - new(3, "Do the laundry", DateOnly.FromDateTime(DateTime.Now.AddDays(1))), - new(4, "Clean the bathroom"), - new(5, "Clean the car", DateOnly.FromDateTime(DateTime.Now.AddDays(2))) -}; + var rawQueryData = context.Request.QueryString.ToString(); + var queryDataDic = context.Request.Query.ToDictionary(k => k.Key, v => v.Value); + foreach (var a in queryDataDic) + { + Console.WriteLine($"""{a.Key}: {a.Value}"""); + } + + if (subscribers.TryGetValue(feedId, out var subscribersList)) + { + foreach (var writer in subscribersList) + { + await writer.WriteLineAsync(rawQueryData); + await writer.FlushAsync(); + } + } +}); -var todosApi = app.MapGroup("/todos"); -todosApi.MapGet("/", () => sampleTodos); -todosApi.MapGet("/{id}", (int id) => - sampleTodos.FirstOrDefault(a => a.Id == id) is { } todo - ? Results.Ok(todo) - : Results.NotFound()); +var getLiveDataApi = app.MapGroup("/listen/for/data"); +getLiveDataApi.MapGet("/{feedId}", async (CancellationToken cancellationToken,HttpContext context, string feedId) => +{ + context.Response.Headers.ContentType = "text/event-stream"; + var writer = new StreamWriter(context.Response.Body, Encoding.UTF8); + subscribers.GetOrAdd(feedId, _ => new List()).Add(writer); + + try + { + while (!cancellationToken.IsCancellationRequested) + { + await Task.Delay(Timeout.Infinite, cancellationToken); + } + } + catch (OperationCanceledException) + { + } + finally + { + if (subscribers.TryGetValue(feedId, out var subscribersList)) + { + subscribersList.Remove(writer); + if (subscribersList.Count == 0) + { + subscribers.TryRemove(feedId, out _); + } + + await writer.DisposeAsync(); + Console.WriteLine("Removed subscriber from feed " + feedId); + } + } +}); app.Run(); -public record Todo(int Id, string? Title, DateOnly? DueBy = null, bool IsComplete = false); -[JsonSerializable(typeof(Todo[]))] + +[JsonSerializable(typeof(string))] +[JsonSerializable(typeof(Int32))] internal partial class AppJsonSerializerContext : JsonSerializerContext { } \ No newline at end of file diff --git a/HoolIt/Properties/launchSettings.json b/HoolIt/Properties/launchSettings.json index fc0b99d..480f514 100644 --- a/HoolIt/Properties/launchSettings.json +++ b/HoolIt/Properties/launchSettings.json @@ -4,8 +4,7 @@ "http": { "commandName": "Project", "dotnetRunMessages": true, - "launchBrowser": true, - "launchUrl": "todos", + "launchBrowser": false, "applicationUrl": "http://localhost:5246", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development"