first commit
This commit is contained in:
@@ -0,0 +1,47 @@
|
||||
using System.Collections.Concurrent;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.SignalR;
|
||||
|
||||
namespace F9WebAiTest.Api.Hubs;
|
||||
|
||||
/// <summary>在线用户登记表(用于判断用户是否在线,离线则走"拉取兜底")</summary>
|
||||
public static class OnlineUserRegistry
|
||||
{
|
||||
private static readonly ConcurrentDictionary<long, byte> _users = new();
|
||||
|
||||
public static void Add(long userId) => _users[userId] = 0;
|
||||
|
||||
public static void Remove(long userId) => _users.TryRemove(userId, out _);
|
||||
|
||||
public static bool IsOnline(long userId) => _users.ContainsKey(userId);
|
||||
}
|
||||
|
||||
/// <summary>通知推送 Hub(客户端连接后按 UserId 标识,服务端用 Clients.User(userId) 定向推送)</summary>
|
||||
public class NotificationHub : Hub
|
||||
{
|
||||
public override async Task OnConnectedAsync()
|
||||
{
|
||||
var userId = GetUserId();
|
||||
if (userId > 0) OnlineUserRegistry.Add(userId);
|
||||
await base.OnConnectedAsync();
|
||||
}
|
||||
public override async Task OnDisconnectedAsync(Exception exception)
|
||||
{
|
||||
var userId = GetUserId();
|
||||
if (userId > 0) OnlineUserRegistry.Remove(userId);
|
||||
await base.OnDisconnectedAsync(exception);
|
||||
}
|
||||
|
||||
private long GetUserId()
|
||||
{
|
||||
var raw = Context.User?.FindFirst("id")?.Value;
|
||||
return long.TryParse(raw, out var id) ? id : 0;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>自定义用户标识:使用 JWT 中的 "id" 声明作为 SignalR 的 UserIdentifier</summary>
|
||||
public class NotificationUserIdProvider : IUserIdProvider
|
||||
{
|
||||
public string GetUserId(HubConnectionContext connection)
|
||||
=> connection.User?.FindFirst("id")?.Value ?? connection.ConnectionId;
|
||||
}
|
||||
Reference in New Issue
Block a user