Files
space-game/apps/backend/Program.cs

59 lines
2.0 KiB
C#

using SpaceGame.Simulation.Api.Simulation;
using System.Text.Json;
var builder = WebApplication.CreateBuilder(args);
var sseJsonOptions = new JsonSerializerOptions(JsonSerializerDefaults.Web);
builder.WebHost.UseUrls("http://127.0.0.1:5079");
builder.Services.AddCors((options) =>
{
options.AddDefaultPolicy((policy) =>
{
policy
.AllowAnyHeader()
.AllowAnyMethod()
.AllowAnyOrigin();
});
});
builder.Services.AddSingleton<WorldService>();
builder.Services.AddHostedService<SimulationHostedService>();
var app = builder.Build();
app.UseCors();
app.MapGet("/", () => Results.Redirect("/api/world"));
app.MapGet("/api/world", (WorldService worldService) => Results.Ok(worldService.GetSnapshot()));
app.MapGet("/api/world/stream", async (HttpContext httpContext, WorldService worldService, CancellationToken cancellationToken) =>
{
httpContext.Response.Headers.Append("Cache-Control", "no-cache");
httpContext.Response.Headers.Append("Content-Type", "text/event-stream");
var afterSequenceRaw = httpContext.Request.Query["afterSequence"].ToString();
_ = long.TryParse(afterSequenceRaw, out var afterSequence);
var stream = worldService.Subscribe(afterSequence, cancellationToken);
await httpContext.Response.WriteAsync(": connected\n\n", cancellationToken);
await httpContext.Response.Body.FlushAsync(cancellationToken);
await foreach (var delta in stream.ReadAllAsync(cancellationToken))
{
var payload = JsonSerializer.Serialize(delta, sseJsonOptions);
await httpContext.Response.WriteAsync($"event: world-delta\ndata: {payload}\n\n", cancellationToken);
await httpContext.Response.Body.FlushAsync(cancellationToken);
}
});
app.MapGet("/api/world/health", (WorldService worldService) => Results.Ok(new
{
ok = true,
sequence = worldService.GetStatus().Sequence,
generatedAtUtc = worldService.GetStatus().GeneratedAtUtc,
}));
app.MapPost("/api/world/reset", (WorldService worldService) =>
{
var snapshot = worldService.Reset();
return Results.Ok(snapshot);
});
app.Run();