Как отправить сообщение SignalR пользователю? - PullRequest
0 голосов
/ 02 октября 2018

Как клиент разрешает отправить сообщение пользователю?

Отправка с контроллера

hubContext.Clients.User(User.Identity.Name).SendAsync();

На данный момент сообщение не отправлено.Нужно ли что-то добавить в OnConnection ()?Или у SignalR есть готовый механизм сопоставления для ConnectionId и User.Identity.Name?

Вот как я это реализовал в данный момент, но мне кажется, это не совсем правильно.Вопрос в том, как сделать такие же стандартные инструменты?

    public static class HubConnections
{
    public static Dictionary<string, List<string>> Users = new Dictionary<string, List<string>>();

    public static List<string> GetUserId(string name)
    {
        return Users[name];
    }
}

public class GameHub : Hub
{
    public override Task OnConnectedAsync()
    {


        if (Context.User.Identity.IsAuthenticated 
            && HubConnections.Users.ContainsKey(Context.User.Identity.Name) 
            && !HubConnections.Users[Context.User.Identity.Name].Contains(Context.ConnectionId))
                HubConnections.Users[Context.User.Identity.Name].Add(Context.ConnectionId);
        else 
            HubConnections.Users.Add(Context.User.Identity.Name, new List<string> { Context.ConnectionId });

        return base.OnConnectedAsync();
    }

    public override Task OnDisconnectedAsync(Exception exception)
    {
        if (Context.User.Identity.IsAuthenticated) HubConnections.Users.Remove(Context.User.Identity.Name);

        return base.OnDisconnectedAsync(exception);
    }
}

Как я уже говорил выше, я попробовал так же, и это не работает

hubContext.Clients.User(User.Identity.Name).SendAsync();

Ответы [ 3 ]

0 голосов
/ 03 октября 2018

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

public void SendMessage(string username, object data)
{
    var connections = HubConnections.Users[Context.User.Identity.Name];

    foreach(var id in connections)
    {
        Clients.client(id).SendAsync("Foo", data);
    }
}
0 голосов
/ 05 октября 2018

Преследовал ту же проблему и получил решение от https://github.com/aspnet/SignalR/issues/2498

Необходимо установить утверждение NameIdentifier.Это тот, который проверил SignalR вместо утверждения Name, которое я принял.Я установил утверждение NameIdentifier и получил свой не-хаб-класс для отправки уведомления определенному пользователю.

0 голосов
/ 02 октября 2018

Есть клиентский компонент.Вы должны сослаться на файл SignalR JS, создать соединение и затем подписаться на конкретное сообщение с сервера.Только тогда отправка этого сообщения действительно сделает что-то.

<script src="~/lib/signalr/signalr.js"></script>
<script>
    const connection = new signalR.HubConnectionBuilder()
       .withUrl("/gameHub")
       .configureLogging(signalR.LogLevel.Information)
       .build();

    connection.on("Foo", (data) => {
        // do something
    });

    connection.start().catch(err => console.error(err.toString()));
</script>

Вышеуказанное заставит клиента запускать функцию, определенную для "Foo" выше, всякий раз, когда сервер отправляет сообщение "Foo", например:

hubContext.Clients.User(User.Identity.Name).SendAsync("Foo", data);
...