Данное руководство устарело. Актуальное руководство: Руководство по ASP.NET Core 7
Для взаимодействия с клиентами в классе 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>
И после условного добавления товара клиент получит одно сообщение:
А все остальные подключенные клиенты получат своего рода push-уведомление о произведенных действиях:
Также мы могли бы переписать метод 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 выполняет все те же действия, только теперь для определения клиентов для отправки сообщений применяется идентификатор клиента, который получаем из контекста хаба.