sozsoft-platform/api/src/Sozsoft.Platform.Application/Notifications/NotificationHub.cs

48 lines
1.7 KiB
C#
Raw Normal View History

using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.SignalR;
using Volo.Abp.Security.Claims;
namespace Sozsoft.Platform.Notifications;
/// <summary>
/// Bildirimlerin aninda duyuruldugu baglanti. Istemci yalnizca dinler; okundu/gosterildi
/// isaretleri REST ucundan gider, boylece yetki ve dogrulama tek yoldan gecer.
/// <para>
/// Kullanici ve kiraci bilgisi baglantinin claim'lerinden okunur: hub cagrilari HTTP ardisik
/// duzeni disinda calistigi icin AsyncLocal tabanli <c>ICurrentUser</c> her zaman dolu olmaz.
/// </para>
/// </summary>
[Authorize]
public class NotificationHub : Hub
{
/// <summary>Istemcinin dinledigi olay adi; yeni bildirim uretildiginde tetiklenir.</summary>
public const string NotificationReceived = "NotificationReceived";
public override async Task OnConnectedAsync()
{
var (tenantId, userId) = GetConnectionIdentity();
if (userId.HasValue)
{
await Groups.AddToGroupAsync(Context.ConnectionId, UserGroupName(tenantId, userId.Value));
}
await base.OnConnectedAsync();
}
private (Guid? TenantId, Guid? UserId) GetConnectionIdentity()
{
var user = Context.User;
return (ParseGuid(user?.FindFirst(AbpClaimTypes.TenantId)?.Value),
ParseGuid(user?.FindFirst(AbpClaimTypes.UserId)?.Value));
}
private static Guid? ParseGuid(string? value) =>
Guid.TryParse(value, out var parsed) ? parsed : null;
/// <summary>Bildirimler kullanici bazlidir; grup adi kiraci ile birlikte anahtarlanir.</summary>
public static string UserGroupName(Guid? tenantId, Guid userId) =>
$"notification:user:{tenantId?.ToString("N") ?? "host"}:{userId:N}";
}