В прошлых темах из хаба в клиент и из клиента в хаб передавались довольно простые данные - одна или две строки. Однако 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)
.
Подобным образом можно отправлять массивы и коллекции, в том числе коллекции сложных данных. Например, определим хаб, который принимает список строк:
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, наоборот, получаем пришедшие данные и выводим на страницу.