You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Blazor Server中如何列出所有会话并查询活跃用户列表

枚举活跃Blazor会话实现活跃用户列表方案

核心实现逻辑

Blazor Server 每个客户端连接会创建独立的依赖注入作用域,IAuthenticationStateProvider 属于作用域服务,我们可以通过「单例会话管理服务+电路生命周期监听」的方式实现活跃会话追踪,全程不需要依赖HTTP会话。

具体实现步骤

  • 第一步:定义活跃会话存储实体
public class ActiveBlazorSession
{
    public string SessionId { get; set; } = Guid.NewGuid().ToString();
    public ClaimsPrincipal User { get; set; }
    public DateTimeOffset ConnectedAt { get; set; } = DateTimeOffset.UtcNow;
    // 可自定义扩展客户端IP、当前访问页面等字段
}
  • 第二步:创建单例会话管理服务
public class BlazorSessionManager
{
    // 线程安全字典避免并发操作异常
    private readonly ConcurrentDictionary<string, ActiveBlazorSession> _activeSessions = new();

    public void AddSession(string sessionId, ActiveBlazorSession session)
    {
        _activeSessions.TryAdd(sessionId, session);
    }

    public void RemoveSession(string sessionId)
    {
        _activeSessions.TryRemove(sessionId, out _);
    }

    // 对外提供查询活跃会话的方法
    public IEnumerable<ActiveBlazorSession> GetActiveSessions()
    {
        return _activeSessions.Values.ToList();
    }
}

在Program.cs中注册为全局单例:
builder.Services.AddSingleton<BlazorSessionManager>();

  • 第三步:通过CircuitHandler监听Blazor连接生命周期
    Blazor Server的每个长连接对应一个Circuit(电路),通过CircuitHandler可以精准监听到连接的创建、断开事件,比组件生命周期监听更可靠:
public class SessionTrackingCircuitHandler : CircuitHandler
{
    private readonly BlazorSessionManager _sessionManager;
    private readonly IAuthenticationStateProvider _authStateProvider;
    private string _currentSessionId;

    public SessionTrackingCircuitHandler(BlazorSessionManager sessionManager, IAuthenticationStateProvider authStateProvider)
    {
        _sessionManager = sessionManager;
        _authStateProvider = authStateProvider;
    }

    public override async Task OnCircuitOpenedAsync(Circuit circuit, CancellationToken cancellationToken)
    {
        var authState = await _authStateProvider.GetAuthenticationStateAsync();
        // 只记录已登录的用户会话,未登录可按需调整逻辑
        if (authState.User.Identity?.IsAuthenticated == true)
        {
            _currentSessionId = circuit.Id;
            var session = new ActiveBlazorSession
            {
                SessionId = circuit.Id,
                User = authState.User
            };
            _sessionManager.AddSession(_currentSessionId, session);
        }
        await base.OnCircuitOpenedAsync(circuit, cancellationToken);
    }

    public override Task OnCircuitClosedAsync(Circuit circuit, CancellationToken cancellationToken)
    {
        if (!string.IsNullOrEmpty(_currentSessionId))
        {
            _sessionManager.RemoveSession(_currentSessionId);
        }
        return base.OnCircuitClosedAsync(circuit, cancellationToken);
    }
}

在Program.cs中注册为作用域服务:
builder.Services.AddScoped<CircuitHandler, SessionTrackingCircuitHandler>();

  • 第四步:获取活跃用户列表
    在需要展示活跃用户的组件或者服务中注入BlazorSessionManager,调用GetActiveSessions()方法即可获取所有活跃会话,可通过User对象的声明获取用户名、用户ID等信息,多标签页登录的同个用户可以通过用户ID去重得到唯一活跃用户列表。

注意事项

  • 以上方案仅适用于Blazor Server场景,如果是Blazor WebAssembly,需要客户端定时向服务端发送心跳包,服务端维护活跃用户列表,超时自动清理
  • Circuit断开事件存在一定的系统延迟,如果需要更精准的在线状态判断,可以额外加心跳逻辑定期更新会话最后活跃时间,清理超过阈值的无效会话
  • 对外展示用户信息前需要做脱敏处理,不要暴露ClaimsPrincipal中的敏感字段

内容的提问来源于stack exchange,提问作者Liero

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 00:54:03