diff --git a/Streetwriters.Messenger/Helpers/SSEHelper.cs b/Streetwriters.Messenger/Helpers/SSEHelper.cs
index 7481bfc..df1c6cb 100644
--- a/Streetwriters.Messenger/Helpers/SSEHelper.cs
+++ b/Streetwriters.Messenger/Helpers/SSEHelper.cs
@@ -18,28 +18,49 @@ along with this program. If not, see .
*/
using System.Linq;
+using System;
+using System.Threading;
using System.Threading.Tasks;
using Lib.AspNetCore.ServerSentEvents;
using System.Security.Claims;
+using System.Collections.Generic;
namespace Streetwriters.Messenger.Helpers
{
public class SSEHelper
{
- public static async Task SendEventToUserAsync(string data, IServerSentEventsService sseService, string userId, string? originTokenId = null)
+ public static async Task SendEventToUserAsync(string data, IServerSentEventsService sseService, string userId, string? originTokenId = null, CancellationToken cancellationToken = default)
{
- var clients = sseService.GetClients().Where(c => c.User.FindFirstValue("sub") == userId);
- foreach (var client in clients)
- {
- if (originTokenId != null && client.User.FindFirstValue("jti") == originTokenId) continue;
- if (!client.IsConnected) continue;
- await client.SendEventAsync(data);
- }
+ var clients = sseService.GetClients()
+ .Where(c => c.User?.FindFirstValue("sub") == userId)
+ .Where(c => originTokenId == null || c.User?.FindFirstValue("jti") != originTokenId);
+
+ await SendEventToClientsAsync(clients, data, cancellationToken);
}
- public static async Task SendEventToAllUsersAsync(string data, IServerSentEventsService sseService)
+ public static async Task SendEventToAllUsersAsync(string data, IServerSentEventsService sseService, CancellationToken cancellationToken = default)
{
- await sseService.SendEventAsync(data);
+ await SendEventToClientsAsync(sseService.GetClients(), data, cancellationToken);
+ }
+
+ private static async Task SendEventToClientsAsync(IEnumerable clients, string data, CancellationToken cancellationToken)
+ {
+ foreach (var client in clients)
+ {
+ if (!client.IsConnected) continue;
+
+ try
+ {
+ await client.SendEventAsync(data, cancellationToken);
+ }
+ catch (OperationCanceledException) when (cancellationToken.IsCancellationRequested)
+ {
+ break;
+ }
+ catch
+ {
+ }
+ }
}
}
}
\ No newline at end of file
diff --git a/Streetwriters.Messenger/Services/HeartbeatService.cs b/Streetwriters.Messenger/Services/HeartbeatService.cs
index f33911a..ce52747 100644
--- a/Streetwriters.Messenger/Services/HeartbeatService.cs
+++ b/Streetwriters.Messenger/Services/HeartbeatService.cs
@@ -21,6 +21,7 @@ using System;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Hosting;
+using Microsoft.Extensions.Logging;
using Lib.AspNetCore.ServerSentEvents;
using Streetwriters.Messenger.Helpers;
using System.Text.Json;
@@ -33,12 +34,14 @@ namespace Streetwriters.Messenger.Services
private const string HEARTBEAT_MESSAGE_FORMAT = "Streetwriters Heartbeat ({0} UTC)";
private readonly IServerSentEventsService _serverSentEventsService;
+ private readonly ILogger _logger;
#endregion
#region Constructor
- public HeartbeatService(IServerSentEventsService serverSentEventsService)
+ public HeartbeatService(IServerSentEventsService serverSentEventsService, ILogger logger)
{
_serverSentEventsService = serverSentEventsService;
+ _logger = logger;
}
#endregion
@@ -47,15 +50,28 @@ namespace Streetwriters.Messenger.Services
{
while (!stoppingToken.IsCancellationRequested)
{
- var message = JsonSerializer.Serialize(new
+ try
{
- type = "heartbeat",
- data = JsonSerializer.Serialize(new
+ var message = JsonSerializer.Serialize(new
{
- t = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()
- })
- });
- await SSEHelper.SendEventToAllUsersAsync(message, _serverSentEventsService);
+ type = "heartbeat",
+ data = JsonSerializer.Serialize(new
+ {
+ t = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()
+ })
+ });
+
+ await SSEHelper.SendEventToAllUsersAsync(message, _serverSentEventsService, stoppingToken);
+ }
+ catch (OperationCanceledException) when (stoppingToken.IsCancellationRequested)
+ {
+ break;
+ }
+ catch (Exception ex)
+ {
+ _logger.LogWarning(ex, "Failed to send SSE heartbeat to one or more clients.");
+ }
+
await Task.Delay(TimeSpan.FromSeconds(5), stoppingToken);
}
}
diff --git a/Streetwriters.Messenger/Streetwriters.Messenger.csproj b/Streetwriters.Messenger/Streetwriters.Messenger.csproj
index 395a829..e71646e 100644
--- a/Streetwriters.Messenger/Streetwriters.Messenger.csproj
+++ b/Streetwriters.Messenger/Streetwriters.Messenger.csproj
@@ -8,7 +8,7 @@
-
+