Как отправить сообщение указанному c пользователю, используя aspnetcore signalR? - PullRequest
0 голосов
/ 18 февраля 2020

У меня есть требование отправить уведомление указанному c пользователю. Я использую do tnet core 3.1. ASPNETCORE signalR для уведомления. Я могу отправлять сообщения всем клиентам, но не могу сделать это для определенного пользователя c.

РЕДАКТИРОВАТЬ 1

Мой концентратор выглядит так:

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);
    }
}

И я вызываю метод SendAsyn c из контроллера как:

 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" });
    }

Ответы [ 2 ]

1 голос
/ 18 февраля 2020

Вы можете отправлять уведомления указанному пользователю, если вам известен идентификатор подключения пользователя или добавить подключенного пользователя в группу.

В концентраторе, если вы знаете идентификатор подключения:

await this.Clients.Client("connectionId").SendAsync("MethodName", "The message");

Вы также можете добавить указанного пользователя в группу и затем отправить сообщение группе:

await this.Groups.AddToGroupAsync("connectionId", "groupName");

await this.Clients.Group("groupName").SendAsync("MethodName", "The message");

Подробнее об этом можно прочитать в этой Документации Microsoft .

Обновление:

Чтобы ответить на ваш обновленный вопрос, вы должны предоставить атрибут авторизации своему концентратору, чтобы иметь имя и другие параметры

[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);
    }
}

И затем на вашем Angular клиенте вы должны предоставить токен для подключения к вашему хабу, например:

private configureSignalR(token: string) {
    this.hubMessageConnection = new signalR.HubConnectionBuilder()
    .configureLogging(signalR.LogLevel.Error).withUrl(this.signalRUrl + "/notifications",
    {
        accessTokenFactory: () => token
    })
    .withAutomaticReconnect()
    .build();
}

Подробнее о Аутентификация и авторизация можно прочитать в документации Microsoft .

1 голос
/ 18 февраля 2020

Вы можете отправить сообщение указанному c пользователю через идентификатор пользователя

В этом примере мы попытаемся получить информацию о текущем пользователе и отправить некоторые данные этому пользователю с помощью пользователя. id:

В концентраторе:

public async Task GetInfo()
{
    var user = await _userManager.GetUserAsync(Context.User);

    await Clients.User(user.Id).SendCoreAsync("msg", new object[] { user.Id, user.Email });
}

В клиенте:

connection.on('msg', function (...data) {
    console.log('data:', data); // ["27010e2f-a47f-4c4e-93af-b55fd95f48a5", "foo@bar.com"]
});

connection.start().then(function () {
    connection.invoke('getinfo');
});

Примечание: Убедитесь, что вы уже сопоставили хаб внутри UseEndpoints метод:

app.UseEndpoints(endpoints =>
{
    endpoints.MapControllerRoute(
        name: "default",
        pattern: "{controller=Home}/{action=Index}/{id?}");

    endpoints.MapHub<YourHubName>("/yourhubname");
});
...