Using signalR in asp.net core, how do I change the userID convention to use the users email address instead of default userId?

心已入冬 提交于 2021-02-20 04:01:36

问题


Im using

    <PackageReference Include="Microsoft.AspNetCore.SignalR.Core" Version="1.1.0" />

in an asp.net core web api. I can see by default that if I want to send a specific user a message I can call a method such as

_hub.Clients.User("c5MOTEmXsEZjoVf-y_sVQD_g-yBis9fvLMbyNJX3M31").SendAsync("MessageUpdated", "ee");

However, I would like to know, is there any way to change this such that I can instead pass in a different value for the userId?

For example, users email address instead?

Is this even possible?

Also, is it possible to detect what the userId is if I have a users email address? Perhaps this second question might help me solve my particular problem better.


回答1:


In definition of User(string userId) and Users(IReadOnlyList<string> userIds), we can find it accepts user ID(s).

is it possible to detect what the userId is if I have a users email address?

If you'd like to send message(s) to specific user(s) based on users email or name etc, you can try to maintain the mapping of user's email to userId(s) or connections, then you can get userId(s) dynamically and send message(s) to specific user(s).

To achieve it, you can refer to the following sample.

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 

Note: above sample (maintain user's email and userId(s) information in a dictionary) is just for testing purpose, in your project, you can maintain user's email and userId(s) information in other data store/storage you want.

Test Result:




回答2:


here is the solution

Update

public void ConfigureServices(IServiceCollection services)

to include

services.AddSingleton<IUserIdProvider, NameUserIdProvider>();

with

public class NameUserIdProvider : IUserIdProvider
{
    public string GetUserId(HubConnectionContext connection)
    {
        return connection.User?.Identity?.Name;
    }
}

Now use can user email address in

_hub.Clients.User(userEmail).SendAsync


来源:https://stackoverflow.com/questions/59296596/using-signalr-in-asp-net-core-how-do-i-change-the-userid-convention-to-use-the

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!