using System; using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; using AsbCloudApp.Data; using AsbCloudApp.Repositories; using AsbCloudApp.Services.Notifications; using AsbCloudInfrastructure.Background; using Microsoft.AspNetCore.SignalR; using Microsoft.Extensions.DependencyInjection; namespace AsbCloudWebApi.SignalR.Services; public class SignalRNotificationTransportService : INotificationTransportService { private readonly NotificationBackgroundWorker backgroundWorker; private readonly ConnectionManagerService connectionManagerService; private readonly IHubContext notificationHubContext; public SignalRNotificationTransportService(NotificationBackgroundWorker backgroundWorker, ConnectionManagerService connectionManagerService, IHubContext notificationHubContext) { this.backgroundWorker = backgroundWorker; this.connectionManagerService = connectionManagerService; this.notificationHubContext = notificationHubContext; } public int IdTransportType => 0; public Task SendAsync(NotificationDto notification, CancellationToken cancellationToken) { var workId = notification.Id.ToString(); if (!backgroundWorker.Contains(workId)) { var connectionId = connectionManagerService.GetConnectionIdByUserId(notification.IdUser); if (!string.IsNullOrWhiteSpace(connectionId)) { var workAction = MakeSignalRSendWorkAction(notification, connectionId); var work = new WorkBase(workId, workAction); backgroundWorker.Push(work); } } return Task.CompletedTask; } public Task SendRangeAsync(IEnumerable notifications, CancellationToken cancellationToken) { var tasks = notifications .Select(notification => SendAsync(notification, cancellationToken)); return Task.WhenAll(tasks); } private Func MakeSignalRSendWorkAction(NotificationDto notification, string connectionId) { const string method = "receiveNotifications"; return async (_, serviceProvider, cancellationToken) => { notification.SentDate = DateTime.UtcNow; await notificationHubContext.Clients.Client(connectionId) .SendAsync(method, notification, cancellationToken); var notificationRepository = serviceProvider.GetRequiredService(); await notificationRepository.UpdateAsync(notification, cancellationToken); }; } }