1. Server Sent Events

Server Sent Events

Server Sent Events (SSE) can be used to push real-time data down to the web browser in an async manner without blocking threads using the IAsyncIEnumerable interface like so:

public class EventStream : EndpointWithoutRequest
{
    public override void Configure()
    {
        Get("event-stream");
        AllowAnonymous();
        Options(x => x.RequireCors(p => p.AllowAnyOrigin()));
    }

    public override async Task HandleAsync(CancellationToken ct)
    {
        //simply provide any IAsyncEnumerable<T> as argument
        await SendEventStream("my-event", GetDataStream(ct), ct);
    }

    private async IAsyncEnumerable<object> GetDataStream(
      [EnumeratorCancellation] CancellationToken cancellation)
    {
        while (!cancellation.IsCancellationRequested)
        {
            await Task.Delay(1000);
            yield return new { guid = Guid.NewGuid() };
        }
    }
}

In the browser, the event stream can be subscribed to and consumed using the EventSource object like so:

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8" />
	</head>
	<body>
		<script>
			const sse = new EventSource('http://localhost:8080/event-stream');
			sse.addEventListener('my-event', (e) => console.log(e.data));
		</script>
	</body>
</html>

If you are planning to create more than a handful of server-sent-event streams, it's a good idea to enable HTTP2 in kestrel and all upstream servers such as reverse proxies and CDNs so that data can be multiplexed between the web server and client using a low number of tcp connections.

Here's a good read on the subject.


© FastEndpoints 2022