Взаимодействие с клиентами

Данное руководство устарело. Актуальное руководство: Руководство по ASP.NET Core 7

Последнее обновление: 24.12.2019

Для взаимодействия с клиентами в классе Hub определено свойство Clients. Оно представляет всех подключенных клиентов в виде объекта IHubCallerClients. Если в классе хаба необходимо вызвать на клиенте функцию и отправить ей некоторые данные, то мы можем использовать данный объект. Например:

public class ChatHub : Hub
{
	public async Task Send(string message)
	{
		await Clients.All.SendAsync("Receive", message);
	}
}

В данном случае у всех подключенных клиентов вызывается функция Receive, которой передается строка message.

У объекта Clients есть следующие свойства:

  • All: представляет всех подключенных клиентов

  • Caller: представляет только текущего клиента, который обратился к хабу

  • Others: представляет всех клиентов за исключением текущего клиента, который обратился к хабу

Кроме свойств объект Clients имеет ряд методов:

  • AllExcept(IReadOnlyList<string> connectionIds): представляет всех клиентов за исключением тех, id которых передаются в метод

  • Client(string connectionId): вызывает метод у клиента по id подключения

  • Clients(IReadOnlyList<string> connectionIds): вызывает метод у клиентов, id которых передаются в метод

  • Group(string groupName): вызывает метод у клиентов определенной группы

  • GroupExcept(string groupName, IReadOnlyList<string> connectionIds): вызывает метод у клиентов группы по имени groupName за исключением тех клиентов, id которых передаются в качестве второго параметра

  • Groups(IReadOnlyList<string> groupNames): вызывает метод у клиентов групп, названия которых передаются в метод

  • OthersInGroup(string OthersInGroup): вызывает метод у клиентов определенной группы за исключением текущего клиента

  • User(string userId): вызывает метод у пользователя по id

  • Users(IReadOnlyList<string> userIds): вызывает метод у пользователей, id которых передаются в метод

Обратите внимание, что концепция клиентов и концепция пользователей в данном случае отличается. Клиент по сути представляет отдельное подключение, с которым ассоциируется определенный идентификатор подключения. Если мы откроем в браузере две вкладки, у нас будет два подключения. А пользователи относятся к системе аутентификации приложения.

Например, определим следующий хаб:

using Microsoft.AspNetCore.SignalR;
using System;
using System.Threading.Tasks;

namespace SignalRApp
{
    public class ChatHub : Hub
    {
        public async Task Send(string product)
        {
            await Clients.Caller.SendAsync("Notify", "Ваш товар добавлен");
            await Clients.Others.SendAsync("Receive", $"Добавлено: {product} в {DateTime.Now.ToShortTimeString()}");
        }
    }
}

При вызове метода Send у текущего клиента будет вызываться функция Notify, а у всех остальных клиентов - функция Receive.

Для теста определим следующую страницу index.html:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>SignalR Chat</title>
</head>
<body>
    <div id="inputForm">
        <input type="text" id="product" />
        <input type="button" id="sendBtn" value="Добавить" />
    </div>
    <div id="status"></div>
    <div id="info"></div>

    <script src="js/signalr/dist/browser/signalr.min.js"></script>
    <script>
        const hubConnection = new signalR.HubConnectionBuilder()
            .withUrl("/chat")
            .build();

        // получение сообщения от сервера
        hubConnection.on('Receive', function (message) {
            
            let elem = document.createElement("p");
            elem.appendChild(document.createTextNode(message));

            var firstElem = document.getElementById("info").firstChild;
            document.getElementById("info").insertBefore(elem, firstElem);

        });
        hubConnection.on('Notify', function (message) {
            document.getElementById("status").innerText = message;
        });

        // отправка сообщения на сервер
        document.getElementById("sendBtn").addEventListener("click", function (e) {
            let product = document.getElementById("product").value;
            hubConnection.invoke('Send', product);
            document.getElementById("product").value = "";
        });

        hubConnection.start();
    </script>
</body>
</html>

И после условного добавления товара клиент получит одно сообщение:

Отправка сообщений сервера клиенту в ASP NET Core SignalR

А все остальные подключенные клиенты получат своего рода push-уведомление о произведенных действиях:

Push уведомления в ASP NET Core SignalR

Также мы могли бы переписать метод Send в хабе следующим образом:

using Microsoft.AspNetCore.SignalR;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;

namespace SignalRApp
{
    public class ChatHub : Hub
    {
        public async Task Send(string product)
        {
            await Clients.Client(Context.ConnectionId).SendAsync("Notify", "Ваш товар добавлен");
            await Clients.AllExcept(new List<string> { Context.ConnectionId }).SendAsync("Receive", $"Добавлено: {product} в {DateTime.Now.ToShortTimeString()}");
        }
    }
}

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

Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850