I am assuming you already have your ASP.NET project ready, I will just straight into implementing SSEs for sending realtime updates to client.
1. Create a Controller for sending SSEs.
public class EventsController : ControllerBase
{
private static readonly List<StreamWriter> _clients = [];
[HttpGet]
public async Task Subscribe()
{
Response.Headers.Append("Content-Type", "text/event-stream");
Response.Headers.Append("Cache-Control", "no-cache");
Response.Headers.Append("Connection", "keep-alive");
var streamWriter = new StreamWriter(Response.Body);
_clients.Add(streamWriter);
try
{
while (!HttpContext.RequestAborted.IsCancellationRequested)
{
await Task.Delay(TimeSpan.FromSeconds(1), HttpContext.RequestAborted);
}
}
finally
{
_clients.Remove(streamWriter);
}
}
public static async Task NotifyClients(string data)
{
List<StreamWriter> deadClients = [];
foreach (var client in _clients)
{
try
{
await client.WriteAsync($"data: {data}\n\n");
await client.FlushAsync();
}
catch
{
deadClients.Add(client);
}
}
foreach (var deadClient in deadClients)
{
_clients.Remove(deadClient);
}
}
}
2. Use the NotifyClients method to send SSEs
Where ever in your code you want to send an event just call the NotifyClients methods with any data. It will be sent to all subscribed clients.
[HttpPost]
public async Task<IActionResult> CreatePost(CreatePostDto createPostDto)
{
// save new post to database
// send SSE to all the clients
await EventsController.NotifyClients("post created");
return Ok("Post created successfully");
}
3. Usage in client-side
const connectToSSE = () => {
const eventSource = new EventSource('/api/events');
eventSource.onmessage = (event) => {
console.log('New data received:', event.data);
// Do something
};
eventSource.onerror = (error) => {
console.error('SSE error:', error);
eventSource.close();
};
};
Top comments (0)