Группы

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

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

Группы в SignalR представляют коллекцию подключений, которые ассоциированы с именем группы. SignalR позволяет добавлять и удалять клиентов из группы. Один клиент может входить сразу в несколько групп.

Для работы с группами в классе Hub определено свойство Groups, которое представляет объект IGroupManager. Он имеет два метода:

  • AddToGroupAsync(connectionId, groupName): добавляет клиента с идентификатором connectionId в группу с именем groupName

  • RemoveFromGroupAsync(connectionId, groupName): удаляет клиента с идентификатором connectionId из группы

Также у объекта IHubCallerClients определено ряд методов, которые позволяют выбрать определенные группы для отправки им сообщения.

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

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

namespace SignalRApp
{
    public class ChatHub : Hub
    {
        string groupname = "cats";
        public async Task Enter(string username)
        {
            if (String.IsNullOrEmpty(username))
            {
                await Clients.Caller.SendAsync("Notify", "Для входа в чат введите логин");
            }
            else
            {
                await Groups.AddToGroupAsync(Context.ConnectionId, groupname);
                await Clients.Group(groupname).SendAsync("Notify", $"{username} вошел в чат");
            }
        }
        public async Task Send(string message, string username)
        {
            await Clients.Group(groupname).SendAsync("Receive", message, username);
        }
    }
}

В хабе определено два метода. В методе Enter обратившегося клиента добавляют в группу "cats". Имя групп может быть любым, важно только учитывать, что оно регистрозависимое. В методе Send ретранслируют сообщение клиента всем участникам группы cats.

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

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

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

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

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

Для тестирования можно определить следующую веб-страницу:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>SignalR Chat</title>
</head>
<body>
    <div id="loginBlock">
        Ввойти в чат:<br />
        <input id="userName" type="text" />
        <input id="loginBtn" type="button" value="Войти" />
    </div><br />

    <div id="header"></div><br />

    <div id="inputForm">
        <input type="text" id="message" />
        <input type="button" id="sendBtn" value="Отправить" />
    </div>
    <div id="chatroom"></div>

    <script src="js/signalr/dist/browser/signalr.min.js"></script>
    <script>
        const hubConnection = new signalR.HubConnectionBuilder()
            .withUrl("/chat")
            .build();
        let userName = "";
        // получение сообщения от сервера
        hubConnection.on("Receive", function (message, userName) {

            // создаем элемент <b> для имени пользователя
            let userNameElem = document.createElement("b");
            userNameElem.appendChild(document.createTextNode(userName + ": "));

            // создает элемент <p> для сообщения пользователя
            let elem = document.createElement("p");
            elem.appendChild(userNameElem);
            elem.appendChild(document.createTextNode(message));

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

        });
        // диагностическое сообщение
        hubConnection.on("Notify", function (message) {

            let elem = document.createElement("p");
            elem.appendChild(document.createTextNode(message));

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

        // установка имени пользователя
        document.getElementById("loginBtn").addEventListener("click", function (e) {
            userName = document.getElementById("userName").value;
            hubConnection.invoke("Enter", userName);
        });
        // отправка сообщения на сервер
        document.getElementById("sendBtn").addEventListener("click", function (e) {
            let message = document.getElementById("message").value;
            hubConnection.invoke("Send", message, userName);
        });

        hubConnection.start();
    </script>
</body>
</html>
Группы в SignalR в ASP.NET Core

При работе с группами стоит учитывать, группа никак не связана с аутентификацией и авторизацией. Например, в примере хаба выше любой подключившийся к хабу и не состояющий в группе "cats", может обратиться к методу Send и отправить сообщение в эту группу, только это сообщение будет видно только членам этой группы. Группа в SignalR - это не более чем условное объединение клиентов, подключенных к хабу. И мы не можем узнать, какие пользователи состоят в той или иной группе, получить всех пользователей определенной группы.

И если, к примеру, необходимо, создавать какие-нибудь групповые чаты, где могут послать сообщения и соответственно видеть эти сообщения только участники данного чата, необходимо использовать стандартные механизмы авторизации и аутентификации. Например:

[Authorize(Roles="admin")]
public async Task Send(string message, string username)
{
	await Clients.Group("admins").SendAsync("Send", message, username);
}

В данном случае в группу "admins" могут посылать сообщения только авторизованные пользователи, у которых роль - "admin".

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