.Net Core SignalR:发送给用户,但来自 IHubContext 的调用方除外(注入控制器)



为了仅在控制器中使用注入的IHubContext时识别当前用户,我存储了一个具有用户ID的组。但是,我正在努力发送给其他人,因为我无法找到找出要排除的连接 ID 的方法。

我的枢纽

public override Task OnConnectedAsync()
{
    Groups.AddAsync(Context.ConnectionId, Context.User.Identity.Name);  
    return base.OnConnectedAsync();
}

在我的控制器方法中,我可以为该用户调用方法:

await _signalRHub.Clients.Group(User.Identity.Name).InvokeAsync("Send", User.Identity.Name + ": Message for you");

IHubContext.Clients.AllExcept 需要一个连接 ID 列表。如何获取已识别用户的连接 ID,以便仅通知其他人?

正如@Pawel所建议的,我现在正在客户端上消除重复数据,这是有效的(好吧,只要您的所有客户端都经过身份验证)。

private async Task Identification() => await Clients.Group(Context.User.Identity.Name).InvokeAsync("Identification", Context.User.Identity.Name);
public override async Task OnConnectedAsync()
{    
    await Groups.AddAsync(Context.ConnectionId, Context.User.Identity.Name);            
    await base.OnConnectedAsync();
    await Identification();
}
与之

配套的JS(缩写):

var connection = new signalR.HubConnection("/theHub");            
var myIdentification;
connection.on("Identification", userId => {
    myIdentification = userId;
});

现在,您可以使用其他方法测试callerIdentification == myIdentification,例如connection.on("something", callerIdentification)

@Tester的评论让我希望在通过 IHubContext 发送时会有更好的方法。

在 SignalR 核心中,connectionId 存储在 SignalR 连接中。假设您有一个定义如下的 signalrR 连接

signalrConnection = new HubConnectionBuilder()
.withUrl('/api/apphub')
...
.build();

每当您发出提取请求时,请将 signalR 连接 ID 添加为标头。例如。

        response = await fetch(url, {
        ...
        headers: {
            'x-signalr-connection': signalrConnection.connectionId,
        },
    });

然后,在控制器中或有权访问 httpContextAccessor 的任何位置,可以使用以下命令排除标头中引用的连接:

    public async Task NotifyUnitSubscribersExceptCaller()
{
    //Grab callers connectionId
    var connectionId = _httpContextAccessor.HttpContext?.Request.Headers["x-signalr-connection"] ?? "";
    await _hub.Clients.GroupExcept("myGroup", connectionId).SendCoreAsync("Sample", new object[] { "Hello World!" });
}

最新更新