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

ASP.NET Core(MVC)使用Windows身份验证时如何给指定用户发送SignalR通知

解决方案

现有方案调整即可实现,无需获取HubConnectionContext

你配置的CustomUserIdProvider本身是可用的,你的核心误区是不需要手动调用IUserIdProvider.GetUserId()方法:该方法是SignalR框架内部在客户端建立Hub连接时自动调用的,用于将连接与对应用户ID绑定,你在业务代码中不需要主动调用。

操作步骤

  1. 首先确保你已经在服务注册逻辑中注入了自定义的用户ID提供器:
// Startup.cs 或 Program.cs
services.AddSingleton<IUserIdProvider, CustomUserIdProvider>();
  1. 控制器中直接获取目标用户的Windows身份用户名即可,分两种场景:
  • 给当前发起POST请求的用户发通知:直接读取控制器内置的User属性即可,该值和CustomUserIdProvider返回的用户ID完全一致:
// API控制器内的代码
var targetUserId = User.Identity?.Name;
if (!string.IsNullOrEmpty(targetUserId))
{
    await _myHub.Clients.User(targetUserId).SendAsync("ReceiveMessage", message);
}
  • 给其他指定用户发通知:直接传入目标用户的Windows用户名(格式为域\用户名或机器名\用户名,和Identity.Name返回格式一致即可)。

替代方案

如果需要更灵活的通知控制,可以选择以下方案:

  • 按组发送:在Hub的OnConnectedAsync生命周期方法中,将当前连接加入对应用户名的分组:
public override async Task OnConnectedAsync()
{
    var userName = Context.User.Identity?.Name;
    if (!string.IsNullOrEmpty(userName))
    {
        await Groups.AddToGroupAsync(Context.ConnectionId, userName);
    }
    await base.OnConnectedAsync();
}

发通知时直接调用对应分组即可:

await _myHub.Clients.Group("目标用户名").SendAsync("ReceiveMessage", message);
  • 自行维护用户-连接映射表:用线程安全的字典存储所有用户的活跃连接ID,在Hub的连接/断开连接生命周期中更新映射,发通知时先查询目标用户的所有连接ID,再批量发送:
// 全局线程安全字典
public static readonly ConcurrentDictionary<string, List<string>> UserConnectionMap = new();

// Hub内连接时添加
public override async Task OnConnectedAsync()
{
    var userName = Context.User.Identity?.Name;
    if (!string.IsNullOrEmpty(userName))
    {
        UserConnectionMap.AddOrUpdate(userName, 
            _ => new List<string> { Context.ConnectionId }, 
            (_, list) => { list.Add(Context.ConnectionId); return list; });
    }
    await base.OnConnectedAsync();
}

// 断开连接时移除
public override async Task OnDisconnectedAsync(Exception exception)
{
    var userName = Context.User.Identity?.Name;
    if (!string.IsNullOrEmpty(userName) && UserConnectionMap.TryGetValue(userName, out var connections))
    {
        connections.Remove(Context.ConnectionId);
        if (connections.Count == 0)
        {
            UserConnectionMap.TryRemove(userName, out _);
        }
    }
    await base.OnDisconnectedAsync(exception);
}

控制器发消息代码:

if (UserConnectionMap.TryGetValue("目标用户名", out var connections))
{
    await _myHub.Clients.Clients(connections).SendAsync("ReceiveMessage", message);
}

注意事项

  • 需确保SignalR的Hub端点启用了Windows身份验证,禁止匿名访问,否则连接上下文中的用户身份会为空。
  • 前端建立SignalR连接时需开启凭证携带配置,例如JS端创建HubConnection时设置withCredentials: true。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.15 09:06:03