Asp.net core 在asp.net核心中使用signalR,如何更改用户ID约定以使用用户电子邮件地址而不是默认用户ID?
我正在使用Asp.net core 在asp.net核心中使用signalR,如何更改用户ID约定以使用用户电子邮件地址而不是默认用户ID?,asp.net-core,signalr,Asp.net Core,Signalr,我正在使用 <PackageReference Include="Microsoft.AspNetCore.SignalR.Core" Version="1.1.0" /> 然而,我想知道,是否有任何方法可以改变这一点,这样我就可以为userId传递一个不同的值 例如,用户是否改为使用电子邮件地址 这可能吗 另外,如果我有一个用户的电子邮件地址,是否可以检测用户ID是什么?也许第二个问题可以帮助我更好地解决我的问题 在用户(string userId)和用户(IReadOn
<PackageReference Include="Microsoft.AspNetCore.SignalR.Core" Version="1.1.0" />
然而,我想知道,是否有任何方法可以改变这一点,这样我就可以为userId传递一个不同的值
例如,用户是否改为使用电子邮件地址
这可能吗
另外,如果我有一个用户的电子邮件地址,是否可以检测用户ID是什么?也许第二个问题可以帮助我更好地解决我的问题 在
用户(string userId)
和用户(IReadOnlyList userId)
的定义中,我们可以发现它接受用户ID
如果我有用户的电子邮件地址,是否可以检测用户ID
如果您希望根据用户电子邮件或姓名等向特定用户发送消息,您可以尝试维护用户电子邮件到用户ID或连接的映射,然后您可以动态获取用户ID并向特定用户发送消息
要实现它,您可以参考以下示例
private static Dictionary<string, List<string>> NtoIdMappingTable = new Dictionary<string, List<string>>();
public async Task SendMessage(string user, string message)
{
await Clients.All.SendAsync("ReceiveMessage", user, message);
}
public async Task SendPrivateMessage(string user, string receiver, string message)
{
var userId = NtoIdMappingTable.GetValueOrDefault(receiver);
await Clients.Users(userId).SendAsync("ReceiveMessage", user, $"{ message}(Private Mes)");
}
public override async Task OnConnectedAsync()
{
var username = Context.User.Identity.Name;
var userId = Context.UserIdentifier;
List<string> userIds;
if (!NtoIdMappingTable.TryGetValue(username, out userIds))
{
userIds = new List<string>();
userIds.Add(userId);
NtoIdMappingTable.Add(username, userIds);
}
else
{
userIds.Add(userId);
}
await base.OnConnectedAsync();
}
//other code logic
private static Dictionary NtoIdMappingTable=new Dictionary();
公共异步任务SendMessage(字符串用户,字符串消息)
{
等待Clients.All.SendAsync(“ReceiveMessage”,user,message);
}
公共异步任务SendPrivateMessage(字符串用户、字符串接收器、字符串消息)
{
var userId=NtoIdMappingTable.GetValueOrDefault(接收方);
wait Clients.Users(userId.SendAsync(“ReceiveMessage”,user,$“{message}(Private Mes)”);
}
公共覆盖异步任务OnConnectedAsync()
{
var username=Context.User.Identity.Name;
var userId=Context.UserIdentifier;
列出用户ID;
if(!NtoIdMappingTable.TryGetValue(用户名,out userid))
{
userIds=newlist();
添加(userId);
NtoIdMappingTable.Add(用户名、用户标识);
}
其他的
{
添加(userId);
}
等待base.OnConnectedAsync();
}
//其他代码逻辑
注意:上面的示例(在字典中维护用户的电子邮件和用户ID信息)仅用于测试目的,在您的项目中,您可以在您想要的其他数据存储/存储中维护用户的电子邮件和用户ID信息
测试结果:
以下是解决方案
更新
public void ConfigureServices(IServiceCollection services)
包括
services.AddSingleton<IUserIdProvider, NameUserIdProvider>();
现在可以在中使用用户电子邮件地址
_hub.Clients.User(userEmail).SendAsync
这很有帮助。但是,我不确定这是否对我有帮助,因为我需要在hub类之外调用_smsHub.Clients.User(),比如在应用程序服务中的某个地方。我很难理解Context.UserIdentifier是如何设置的。如果应用层服务器端需要向用户发送消息,那么代码应该如何获得用户标识符列表?我真的应该在OnConnectedAsync上保留所有用户标识符吗?对于我来说,我似乎有点奇怪,我必须依靠自己来坚持标识符集。根据您上面的示例,我理解客户端可以手动输入目标接收器。但是,例如,应用程序服务中的服务器端代码如何确定接收器/用户ID的可接受值?例如,假设我有一个控制器,控制器知道用户的电子邮件地址。控制器如何仅基于电子邮件向用户发送消息?我可以看出,1种解决方案可能是将用户电子邮件+标识符OnConnectedAsync持久化到repo中,然后使用控制器中的repo来获取用户标识符。这是唯一的办法吗?有没有其他方法,这样我就不必编写所有的持久性代码,并用这些信息维护一个DB表?我开始阅读更多关于这方面的内容。听起来我并不是唯一一个希望在库中维护的类中列出所有用户的人。我希望知道这是否是库中的功能请求,这样我就可以避免自己编写代码了/你能解释一下它是怎么工作的吗?我在试你的东西,但没法用。
public class NameUserIdProvider : IUserIdProvider
{
public string GetUserId(HubConnectionContext connection)
{
return connection.User?.Identity?.Name;
}
}
_hub.Clients.User(userEmail).SendAsync