问题
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