问题
I have a requirement to send notification to specific user. I am using dotnet core 3.1. ASPNETCORE signalR for the notification. I am able to send the messages to all clients but unablt to do so for specific user.
EDIT 1
My Hub looks like :
public class NotificationHub : Hub
{
public override async Task OnConnectedAsync()
{
await Groups.AddToGroupAsync(Context.ConnectionId, Context.User.Identity.Name);
await base.OnConnectedAsync();
}
public override async Task OnDisconnectedAsync(Exception ex)
{
await Groups.RemoveFromGroupAsync(Context.ConnectionId, Context.User.Identity.Name);
await base.OnDisconnectedAsync(ex);
}
}
And i am calling the SendAsync method from Controller as :
private IHubContext<NotificationHub> _hub;
public NotificationController(IHubContext<NotificationHub> hub)
{
_hub = hub;
}
[HttpGet]
public IActionResult Get()
{
//_hub.Clients.All.SendAsync("SendMessage",
_hub.Clients.All.SendAsync("SendMessage",
new
{
val1 = getRandomString(),
val2 = getRandomString(),
val3 = getRandomString(),
val4 = getRandomString()
});
return Ok(new { Message = "Request Completed" });
}
回答1:
You can send message to specific user via user id
In this example, we will try to get current user info and send some data back to that user using user id:
In the hub:
public async Task GetInfo()
{
var user = await _userManager.GetUserAsync(Context.User);
await Clients.User(user.Id).SendCoreAsync("msg", new object[] { user.Id, user.Email });
}
In the client:
connection.on('msg', function (...data) {
console.log('data:', data); // ["27010e2f-a47f-4c4e-93af-b55fd95f48a5", "foo@bar.com"]
});
connection.start().then(function () {
connection.invoke('getinfo');
});
Note: Make sure you've already mapped the hub inside UseEndpoints
method:
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
endpoints.MapHub<YourHubName>("/yourhubname");
});
回答2:
You can send notifications to a specified if you know the users connectionId or add the connected user to an group.
In the hub, assuming you know the connectionId:
await this.Clients.Client("connectionId").SendAsync("MethodName", "The message");
You also can add a specified user in to a group and then send the message to the group:
await this.Groups.AddToGroupAsync("connectionId", "groupName");
await this.Clients.Group("groupName").SendAsync("MethodName", "The message");
You can read more about it in this Microsoft Documentation.
Update:
To answer your updated question, you must provide the authorization attribute to your hub in order to have identity name and other parameters
[Authorize]
public class NotificationHub : Hub
{
public override async Task OnConnectedAsync()
{
await Groups.AddToGroupAsync(Context.ConnectionId, Context.User.Identity.Name);
await base.OnConnectedAsync();
}
public override async Task OnDisconnectedAsync(Exception ex)
{
await Groups.RemoveFromGroupAsync(Context.ConnectionId, Context.User.Identity.Name);
await base.OnDisconnectedAsync(ex);
}
}
And then on your Angular client, you must provide a token to connect to your hub like:
private configureSignalR(token: string) {
this.hubMessageConnection = new signalR.HubConnectionBuilder()
.configureLogging(signalR.LogLevel.Error).withUrl(this.signalRUrl + "/notifications",
{
accessTokenFactory: () => token
})
.withAutomaticReconnect()
.build();
}
You can read more about Authentication and authorization in the microsoft documentation.
来源:https://stackoverflow.com/questions/60275474/how-to-send-a-message-to-specific-user-using-aspnetcore-signalr