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