我正在尝试使用 Angular 作为客户端应用程序创建一个 .net core 3.0 SignalR 项目。我已经在客户端和服务器之间建立了成功的连接,并向所有连接的客户端发送了消息。我打算将消息发送给特定用户而不是所有连接的客户端。为此,我尝试使用 ConnectionId、UserIdentifier 和 User.Identity.Name。
我的服务器端代码/消息中心
namespace SignalR_server
{
public class MessageHub : Hub
{
public static ConcurrentDictionary<string, string> MyUsers = new ConcurrentDictionary<string, string>();
public override Task OnConnectedAsync()
{
string name = Context.User.Identity.Name;
MyUsers.TryAdd( Context.ConnectionId,name);
return base.OnConnectedAsync();
}
public override Task OnDisconnectedAsync(Exception exception)
{
string garbage;
MyUsers.TryRemove(Context.ConnectionId, out garbage);
return base.OnDisconnectedAsync(exception);
}
public void Send(string msg)
{
string strMessage = string.Empty;
Clients.All.SendAsync("transfermessage",strMessage);
}
public string GetConnectionID()
{
return Context.ConnectionId;
}
public string GetUserIdentifier()
{
return Context.UserIdentifier;
}
public string GetUserName()
{
return Context.User.Identity.Name;
}
public Task SendPrivateMessage(string user, string message)
{
return Clients.Users(user).SendAsync("transfermessage1", message);
}
}
}
客户端/Angular 代码
public startConnection = () => {
this.hubConnection = new signalR.HubConnectionBuilder()
.withUrl('https://localhost:44363/message',{
skipNegotiation: true,
transport: signalR.HttpTransportType.WebSockets
})
.build();
this.hubConnection
.start()
.then(() => {
console.log('Connection Started')
console.log('Connection ID: ')
console.log(this.hubConnection.invoke("GetConnectionID"))
console.log('User Identifier: ')
console.log(this.hubConnection.invoke("GetUserIdentifier"))
console.log('User Name: ')
console.log(this.hubConnection.invoke("GetUserName"))
// console.log(this.hubConnection.invoke("SendPrivateMessage","Myuser","test message"))
})
.catch(err => console.log('Error while connecting: ' + err))
}
每当连接新客户端时,我都可以看到 connectionId
的值,但是 UserIdentifier
,User.Identity.Name
结果是空。
我不确定为什么会这样;我是不是遗漏了什么或者需要做些什么来定义 UserIdentifers?
最佳答案
在我看来,您需要为您创建的 Hubs 类指定 [Auhtorize] 属性,并实现 IUserIdProvider,然后将其注册到 Startup.cs 类中。
<强>1。在 Hub 上执行此操作:
[Authorize]
public class MessageHub : Hub
{
// Code removed for brevity
}
<强>2。根据需要为用户 ID 或名称或电子邮件实现 IUserIdProvider
public class IdBasedUserIdProvider : IUserIdProvider
{
public string GetUserId(HubConnectionContext connection)
{
//TODO: Implement USERID Mapper Here
//throw new NotImplementedException();
return connection.User.FindFirst("sub").Value;
}
}
<强>3。在 Startup.cs 类中注册 Provider
public void ConfigureServices(IServiceCollection services)
{
services.AddSignalR();
services.AddSingleton<IUserIdProvider, IdBasedUserIdProvider>();
}
我希望这能帮助你解决你遇到的问题
关于angular - 连接到 SignalR 集线器时将 UserIdentifier 或 User.Identity.Name 设置为 null,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62978452/