forked from ddrilling/AsbCloudServer
Отправка уведомлений
1. Сделал отправку уведомлений через SignalR. 2. Сделал рефакторинг для хабов.
This commit is contained in:
parent
96786b1be7
commit
29a534258e
@ -0,0 +1,8 @@
|
||||
namespace AsbCloudWebApi.Options.Notifications;
|
||||
|
||||
public class NotificationsOptionsSignalR
|
||||
{
|
||||
public string Method { get; set; } = null!;
|
||||
|
||||
public int IdTransport { get; set; }
|
||||
}
|
@ -0,0 +1,82 @@
|
||||
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<NotificationHub> notificationHubContext;
|
||||
private readonly NotificationsOptionsSignalR notificationsOptionsSignalR;
|
||||
private readonly IServiceProvider serviceProvider;
|
||||
|
||||
public SignalRNotificationSender(IConnectionManager connectionManager,
|
||||
INotificationSendingQueueService notificationSendingQueueService,
|
||||
IHubContext<NotificationHub> notificationHubContext,
|
||||
IOptions<NotificationsOptionsSignalR> 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<INotificationRepository>();
|
||||
|
||||
if (notificationRepository != null)
|
||||
{
|
||||
await notificationRepository.UpdateAsync(notification,
|
||||
cancellationToken);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
19
AsbCloudWebApi/SignalR/BaseHub.cs
Normal file
19
AsbCloudWebApi/SignalR/BaseHub.cs
Normal file
@ -0,0 +1,19 @@
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.SignalR;
|
||||
|
||||
namespace AsbCloudWebApi.SignalR;
|
||||
|
||||
public abstract class BaseHub : Hub
|
||||
{
|
||||
public virtual Task AddToGroup(string groupName) =>
|
||||
Groups.AddToGroupAsync(Context.ConnectionId, groupName);
|
||||
|
||||
public virtual Task RemoveFromGroup(string groupName) =>
|
||||
Groups.RemoveFromGroupAsync(Context.ConnectionId, groupName);
|
||||
}
|
||||
|
||||
public abstract class BaseHub<T> : BaseHub
|
||||
where T : class
|
||||
{
|
||||
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
using System.Collections.Concurrent;
|
||||
|
||||
namespace AsbCloudWebApi.SignalR.ConnectionManager;
|
||||
|
||||
public class ConnectionManager : IConnectionManager
|
||||
{
|
||||
private readonly ConcurrentDictionary<string, string> _connections = new();
|
||||
|
||||
public void AddConnection(string userId,
|
||||
string connectionId)
|
||||
{
|
||||
_connections.TryAdd(userId, connectionId);
|
||||
}
|
||||
|
||||
public void RemoveConnection(string userId)
|
||||
{
|
||||
_connections.TryRemove(userId, out _);
|
||||
}
|
||||
|
||||
public string? GetConnectionIdByUserId(string userId)
|
||||
{
|
||||
_connections.TryGetValue(userId, out string? connectionId);
|
||||
return connectionId;
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
namespace AsbCloudWebApi.SignalR.ConnectionManager;
|
||||
|
||||
public interface IConnectionManager
|
||||
{
|
||||
void AddConnection(string userId,
|
||||
string connectionId);
|
||||
|
||||
void RemoveConnection(string userId);
|
||||
|
||||
string? GetConnectionIdByUserId(string userId);
|
||||
}
|
39
AsbCloudWebApi/SignalR/NotificationHub.cs
Normal file
39
AsbCloudWebApi/SignalR/NotificationHub.cs
Normal file
@ -0,0 +1,39 @@
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using AsbCloudApp.Services;
|
||||
using AsbCloudWebApi.Options.Notifications;
|
||||
using AsbCloudWebApi.SignalR.ConnectionManager;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
||||
namespace AsbCloudWebApi.SignalR;
|
||||
|
||||
[Authorize]
|
||||
public class NotificationHub : BaseHub
|
||||
{
|
||||
private readonly IConnectionManager connectionManager;
|
||||
private readonly INotificationService notificationService;
|
||||
private readonly NotificationsOptionsSignalR notificationsOptionsSignalR;
|
||||
|
||||
public NotificationHub(IConnectionManager connectionManager,
|
||||
INotificationService notificationService,
|
||||
IOptions<NotificationsOptionsSignalR> notificationsOptionsSignalR)
|
||||
{
|
||||
this.connectionManager = connectionManager;
|
||||
this.notificationService = notificationService;
|
||||
this.notificationsOptionsSignalR = notificationsOptionsSignalR.Value;
|
||||
}
|
||||
|
||||
public async Task OnConnected(int idUser)
|
||||
{
|
||||
string connectionId = Context.ConnectionId;
|
||||
|
||||
connectionManager.AddConnection(idUser.ToString(), connectionId);
|
||||
|
||||
await notificationService.ResendNotificationAsync(idUser,
|
||||
notificationsOptionsSignalR.IdTransport,
|
||||
CancellationToken.None);
|
||||
|
||||
await base.OnConnectedAsync();
|
||||
}
|
||||
}
|
@ -1,6 +1,4 @@
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.SignalR;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace AsbCloudWebApi.SignalR
|
||||
{
|
||||
@ -8,12 +6,8 @@ namespace AsbCloudWebApi.SignalR
|
||||
// https://docs.microsoft.com/ru-ru/aspnet/core/signalr/introduction?view=aspnetcore-5.0
|
||||
|
||||
[Authorize]
|
||||
public class ReportsHub : Hub<IReportHubClient>
|
||||
public class ReportsHub : BaseHub<IReportHubClient>
|
||||
{
|
||||
public Task AddToGroup(string groupName)
|
||||
=> Groups.AddToGroupAsync(Context.ConnectionId, groupName);
|
||||
|
||||
public Task RemoveFromGroup(string groupName)
|
||||
=> Groups.RemoveFromGroupAsync(Context.ConnectionId, groupName);
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,4 @@
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.SignalR;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace AsbCloudWebApi.SignalR
|
||||
{
|
||||
@ -8,12 +6,8 @@ namespace AsbCloudWebApi.SignalR
|
||||
// https://docs.microsoft.com/ru-ru/aspnet/core/signalr/introduction?view=aspnetcore-5.0
|
||||
|
||||
[Authorize]
|
||||
public class TelemetryHub : Hub
|
||||
public class TelemetryHub : BaseHub
|
||||
{
|
||||
public Task AddToGroup(string groupName)
|
||||
=> Groups.AddToGroupAsync(Context.ConnectionId, groupName.ToString());
|
||||
|
||||
public Task RemoveFromGroup(string groupName)
|
||||
=> Groups.RemoveFromGroupAsync(Context.ConnectionId, groupName);
|
||||
|
||||
}
|
||||
}
|
@ -1,7 +1,10 @@
|
||||
using AsbCloudInfrastructure;
|
||||
using AsbCloudWebApi.Converters;
|
||||
using AsbCloudWebApi.Middlewares;
|
||||
using AsbCloudWebApi.Options.Notifications;
|
||||
using AsbCloudWebApi.SignalR;
|
||||
using AsbCloudWebApi.SignalR.BackgroundServices;
|
||||
using AsbCloudWebApi.SignalR.ConnectionManager;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
@ -44,7 +47,10 @@ namespace AsbCloudWebApi
|
||||
|
||||
services.AddJWTAuthentication();
|
||||
|
||||
services.AddSignalR();
|
||||
services.AddSignalR()
|
||||
.Services.AddSingleton<IConnectionManager, ConnectionManager>()
|
||||
.AddHostedService<SignalRNotificationSender>()
|
||||
.Configure<NotificationsOptionsSignalR>(Configuration.GetSection("NotificationsOptionsSignalR"));
|
||||
|
||||
services.AddCors(options =>
|
||||
{
|
||||
@ -147,6 +153,7 @@ namespace AsbCloudWebApi
|
||||
app.UseEndpoints(endpoints =>
|
||||
{
|
||||
endpoints.MapControllers();
|
||||
endpoints.MapHub<NotificationHub>("/hubs/notifications");
|
||||
endpoints.MapHub<TelemetryHub>("/hubs/telemetry");
|
||||
endpoints.MapHub<ReportsHub>("/hubs/reports");
|
||||
});
|
||||
|
@ -27,6 +27,10 @@
|
||||
"supportMail": "support@digitaldrilling.ru"
|
||||
},
|
||||
"DirectoryNameHelpPageFiles": "helpPages",
|
||||
"NotificationsOptionsSignalR": {
|
||||
"Method": "notifications",
|
||||
"IdTransport": 1
|
||||
},
|
||||
"Urls": "http://0.0.0.0:5000" //;https://0.0.0.0:5001" //,
|
||||
// See https man: https://docs.microsoft.com/en-us/aspnet/core/fundamentals/servers/kestrel/endpoints?view=aspnetcore-6.0
|
||||
//"Kestrel": {
|
||||
|
Loading…
Reference in New Issue
Block a user