为了仅在控制器中使用注入的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!" });
}