我正在从控制器中的外部服务接收带有用户名的消息。我需要分离客户端,但无法在控制器中获取connectionId:hubContext.Clients.Client(connectionId).SendAsync.. 在 .net-core 中,按客户端分离 Signalr 中的调用的最佳方法是什么?
我尝试从js中的控制器调用,然后使用connectionId再次返回,但控制器中没有分隔符 - hubContext.Clients.All.SendAsync .. 我也尝试为外部呼叫设置集线器,但不能。 我是 Signalr 的新手,需要一点帮助。 谢谢
实际上,没有必要获取每个用户的连接ID。
根据 SignalR 用户的此文档。
SignalR 中的单个用户可以与应用程序建立多个连接。为了 例如,用户可以在其桌面上进行连接,也可以在其桌面上进行连接 电话。每个设备都有单独的 SignalR 连接,但它们都是 与同一用户关联。如果消息发送给用户,所有 与该用户关联的连接的数量接收该消息。这 连接的用户标识符可以通过 中心中的 Context.UserIdentifier 属性。
默认情况下,SignalR 使用与连接关联的 ClaimsPrincipal 中的 ClaimTypes.NameIdentifier 作为用户标识符。
因此,如果您想识别每个用户的身份,您应该拥有身份验证模式,例如身份。
然后就可以直接使用身份用户的名字来发送消息给特定的用户了。
如下:
public Task SendPrivateMessage(string user, string message)
{
// the user is the ClaimTypes.NameIdentifier
return Clients.User(user).SendAsync("ReceiveMessage", message);
}
此外,如果您不想使用
ClaimTypes.NameIdentifier
让信号器绑定到连接ID,您可以自定义它。
像这样,这是使用
Email
而不是 NameIdentifier
来与其绑定。
public class EmailBasedUserIdProvider : IUserIdProvider
{
public virtual string GetUserId(HubConnectionContext connection)
{
return connection.User?.FindFirst(ClaimTypes.Email)?.Value!;
}
}
并在program.cs中注册它:
builder.Services.AddSingleton<IUserIdProvider, EmailBasedUserIdProvider>();