Отправка сложных объектов

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

В прошлых темах из хаба в клиент и из клиента в хаб передавались довольно простые данные - одна или две строки. Однако SignalR позволяет связывать наборы данных со сложными объектами. Это значит, что мы можем получать в хабе данные со сложной комплексной структурой.

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

using Microsoft.AspNetCore.SignalR;

namespace SignalRApp
{
    public class ChatHub : Hub
    {
        public async Task Send(User user)
        {
            user.Age += 5;
            await Clients.Caller.SendAsync("Receive", user);
        }
    }
    public class User
    {
        public string Name { get; set; } = "";
        public int Age { get; set; }
    }
}

Для демонстрации здесь хаб получает данные в виде объекта User, изменяет значение его свойства Age и отправляет обратно текущему клиенту.

Также определим следующую веб-страницу для взаимодействия с хабом:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>METANIT.COM</title>
</head>
<body>
    <div>
        <label>Имя</label><br />
        <input type="text" id="name" /><br /><br />
        <label>Возраст</label><br />
        <input type="number" id="age" /><br /><br />
        <input type="button" id="sendBtn" value="Отправить" disabled="disabled" />
    </div>
    <div><p id="response"></p></div>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/microsoft-signalr/6.0.1/signalr.js"></script>
    <script>
        const hubConnection = new signalR.HubConnectionBuilder()
            .withUrl("/chat")
            .build();

        // отправка сообщения на сервер
        document.getElementById("sendBtn").addEventListener("click", function () {
            
            const name = document.getElementById("name").value;
            const age = document.getElementById("age").value;

            hubConnection
                .invoke("Send", { "name": name, "age": parseInt(age) })
                .catch(function (err) {
                    return console.error(err.toString());
            });
        });
        // получение сообщения от сервера
        hubConnection.on("Receive", function (user) {

            document.getElementById("response").innerText = `Имя: ${user.name} Возраст: ${user.age}`;
        });

        hubConnection.start()
            .then(function () {
                document.getElementById("sendBtn").disabled = false;
            })
            .catch(function (err) {
                return console.error(err.toString());
            });
    </script>
</body>
</html>

Код javascript получает введенные в два поля на странице данные, формирует из них объект со свойствами "name" и "age" и отправляет хабу. Стоит обратить внимание, что отправляемые объект соответствует определению класса User, благодаря чему SignalR сможет связать эти данные с объектом User.

Обратите внимание на то, что при отправке для значения age выполняется преобразование parseInt(age).

Отправка объектов в SignalR в ASP.NET Core и C#

Подобным образом можно отправлять массивы и коллекции, в том числе коллекции сложных данных. Например, определим хаб, который принимает список строк:

using Microsoft.AspNetCore.SignalR;

namespace SignalRApp
{
    public class ChatHub : Hub
    {
        public async Task Send(List<string> items)
        {
            await Clients.Caller.SendAsync("Receive", items);
        }
    }
}

Полученный список отправляет обратно клиенту.

На клиенте определим отправку и получение набора строк:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>METANIT.COM</title>
</head>
<body>
    <div>
        <input type="text" name="items" /><br /><br />
        <input type="text" name="items" /><br /><br />
        <input type="text" name="items" /><br /><br />
        <input type="button" id="sendBtn" value="Отправить" disabled="disabled" />
    </div>
    <div><p id="response"></p></div>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/microsoft-signalr/6.0.1/signalr.js"></script>
    <script>
        const hubConnection = new signalR.HubConnectionBuilder()
            .withUrl("/chat")
            .build();

        // отправка сообщения на сервер
        document.getElementById("sendBtn").addEventListener("click", function () {
            
            const itemElems = document.getElementsByName("items");
            const items = [];
            for (let i = 0; i < itemElems.length; i++) {
                items.push(itemElems[i].value);
            }

            hubConnection
                .invoke("Send", items)
                .catch(function (err) {
                    return console.error(err.toString());
            });
        });
        // получение сообщения от сервера
        hubConnection.on("Receive", function (data) {

            document.getElementById("response").innerHTML = "";
            for (let i = 0; i < data.length; i++) {

                document.getElementById("response").innerHTML += `<p>${data[i]}</p>`;
            }
        });

        hubConnection.start()
            .then(function () {
                document.getElementById("sendBtn").disabled = false;
            })
            .catch(function (err) {
                return console.error(err.toString());
            });
    </script>
</body>
</html>

На странице три поля ввода, имя которых равно "items". В коде javascript считываем значения этих полей, добавляем их в массив и отправляем хабу.

В функции Receive, наоборот, получаем пришедшие данные и выводим на страницу.

Отправка массивов в SignalR в приложении на ASP.NET Core и C#
Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850