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 Microsoft.AspNetCore.SignalR; namespace AsbCloudWebApi.SignalR.Services; public class SignalRNotificationTransportService : INotificationTransportService { private readonly ConnectionManagerService connectionManagerService; private readonly IHubContext notificationHubContext; private readonly INotificationRepository notificationRepository; private readonly SemaphoreSlim semaphoreSlim = new (1, 1); public SignalRNotificationTransportService(ConnectionManagerService connectionManagerService, IHubContext notificationHubContext, INotificationRepository notificationRepository) { this.connectionManagerService = connectionManagerService; this.notificationHubContext = notificationHubContext; this.notificationRepository = notificationRepository; } public int IdTransportType => 0; public async Task SendAsync(NotificationDto notification, CancellationToken cancellationToken) { const string method = "receiveNotifications"; var connectionId = connectionManagerService.GetConnectionIdByUserId(notification.IdUser); if (!string.IsNullOrWhiteSpace(connectionId)) { notification.SentDate = DateTime.UtcNow; await notificationHubContext.Clients.Client(connectionId) .SendAsync(method, notification, cancellationToken); await semaphoreSlim.WaitAsync(cancellationToken); await notificationRepository.UpdateAsync(notification, cancellationToken); semaphoreSlim.Release(); } } public Task SendRangeAsync(IEnumerable notifications, CancellationToken cancellationToken) { var tasks = notifications .Select(notification => SendAsync(notification, cancellationToken)); return Task.WhenAll(tasks); } }