using System; using System.Threading; using System.Threading.Tasks; using AsbCloudApp.Repositories; using AsbCloudApp.Services; using AsbCloudWebApi.Options.Notifications; using AsbCloudWebApi.SignalR.ConnectionManager; using Microsoft.AspNetCore.SignalR; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Options; namespace AsbCloudWebApi.SignalR.BackgroundServices; public class SignalRNotificationSender : BackgroundService { private readonly IConnectionManager connectionManager; private readonly INotificationSendingQueueService notificationSendingQueueService; private readonly IHubContext notificationHubContext; private readonly NotificationsOptionsSignalR notificationsOptionsSignalR; private readonly IServiceProvider serviceProvider; public SignalRNotificationSender(IConnectionManager connectionManager, INotificationSendingQueueService notificationSendingQueueService, IHubContext notificationHubContext, IOptions notificationsOptionsSignalR, IServiceProvider serviceProvider) { this.connectionManager = connectionManager; this.notificationSendingQueueService = notificationSendingQueueService; this.notificationHubContext = notificationHubContext; this.notificationsOptionsSignalR = notificationsOptionsSignalR.Value; this.serviceProvider = serviceProvider; } protected override async Task ExecuteAsync(CancellationToken stoppingToken) { await Task.Run( async () => { await SendAsync(stoppingToken); }, stoppingToken); } private async Task SendAsync(CancellationToken cancellationToken) { while (!cancellationToken.IsCancellationRequested) { notificationSendingQueueService.Wait(cancellationToken); while (!notificationSendingQueueService.IsEmpty) { if (notificationSendingQueueService.TryDequeue(out var notification)) { string userId = notification.IdUser.ToString(); var connectionId = connectionManager.GetConnectionIdByUserId(userId); if (!string.IsNullOrWhiteSpace(connectionId)) { await notificationHubContext.Clients.Client(connectionId) .SendAsync(notificationsOptionsSignalR.Method, notification, cancellationToken); notification.SentDateAtUtc = DateTime.UtcNow; notification.IsRead = false; } var scope = serviceProvider.CreateScope(); var notificationRepository = scope.ServiceProvider.GetService(); if (notificationRepository != null) { await notificationRepository.UpdateAsync(notification, cancellationToken); } } } } } }