Центры и подключения SignalR
Создайте центр SignalR, подключите его в ASP.NET Core и установите соединения WebSocket из клиентов JavaScript и .NET.
«Центры и подключения SignalR» — бесплатный урок C# Academy на CoddyKit. Это урок 1 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения C# Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс C# Academy содержит 4 уроков всего.
Что такое SignalR
SignalR — это библиотека ASP.NET Core, добавляющая обмен данными в реальном времени между сервером и клиентами в обоих направлениях. Она автоматически выбирает лучший транспорт — WebSockets, события, отправляемые сервером, или длинный опрос — на основе возможностей обеих сторон.
Настройка SignalR
Добавьте SignalR в службы и сопоставьте конечную точку хаба. Хаб — это класс, обрабатывающий соединения клиентов и вызовы методов.
builder.Services.AddSignalR();
var app = builder.Build();
app.UseCors("AllowAll");
app.MapHub<ChatHub>("/hubs/chat");
app.Run();Создание хаба
Унаследуйтесь от Hub. Методы хаба вызываются клиентами. Свойство Context предоставляет сведения о соединении, а Clients позволяет отправлять сообщения обратно.
using Microsoft.AspNetCore.SignalR;
public class ChatHub : Hub
{
public async Task SendMessage(string user, string message)
{
// Broadcast to ALL connected clients
await Clients.All.SendAsync("ReceiveMessage", user, message);
}
public override async Task OnConnectedAsync()
{
await Clients.Caller.SendAsync("Welcome",
$"Connected as {Context.ConnectionId}");
await base.OnConnectedAsync();
}
}Клиент JavaScript
Официальный JavaScript-клиент SignalR создаёт соединение, регистрирует обработчики событий и запускает соединение. Методы, определённые в хабе, можно вызывать из JavaScript.
// npm install @microsoft/signalr
import * as signalR from "@microsoft/signalr";
const connection = new signalR.HubConnectionBuilder()
.withUrl("/hubs/chat")
.withAutomaticReconnect()
.build();
connection.on("ReceiveMessage", (user, message) => {
console.log(`${user}: ${message}`);
});
await connection.start();
await connection.invoke("SendMessage", "Alice", "Hello!");Клиент SignalR для .NET
Клиент для .NET работает так же — он полезен для обмена данными в реальном времени между службами или для настольных и мобильных приложений.
// dotnet add package Microsoft.AspNetCore.SignalR.Client
var connection = new HubConnectionBuilder()
.WithUrl("https://myapp.com/hubs/chat")
.WithAutomaticReconnect()
.Build();
connection.On<string, string>("ReceiveMessage", (user, msg) =>
Console.WriteLine($"{user}: {msg}"));
await connection.StartAsync();
await connection.InvokeAsync("SendMessage", "Bot", "Connected!");Отправка сообщений определённым клиентам
Свойство Clients содержит методы для выбора определённых соединений, вызывающих клиентов или всех подключённых клиентов, кроме указанных.
// To the caller only
await Clients.Caller.SendAsync("YouSaid", message);
// To a specific connection
await Clients.Client(connectionId).SendAsync("PrivateMsg", msg);
// To all except caller
await Clients.Others.SendAsync("ReceiveMessage", user, message);
// To multiple specific connections
await Clients.Clients(new[] { id1, id2 })
.SendAsync("DirectMsg", msg);Контекст хаба: отправка сообщений вне хаба
Внедрите IHubContext<T> в службы или фоновые рабочие процессы, чтобы отправлять сообщения вне класса хаба — это необходимо для отправки уведомлений, инициированных сервером.
public class NotificationService
{
private readonly IHubContext<ChatHub> _hub;
public NotificationService(IHubContext<ChatHub> hub) => _hub = hub;
public async Task BroadcastAlertAsync(string alert)
{
// Send to all clients from a background service
await _hub.Clients.All.SendAsync("SystemAlert", alert);
}
}События жизненного цикла соединения
Переопределите OnConnectedAsync и OnDisconnectedAsync, чтобы отслеживать соединения, поддерживать состояние или освобождать ресурсы.
public override async Task OnConnectedAsync()
{
_connections.TryAdd(Context.ConnectionId, GetUserName());
await Clients.All.SendAsync("UserJoined", GetUserName());
await base.OnConnectedAsync();
}
public override async Task OnDisconnectedAsync(Exception? ex)
{
_connections.TryRemove(Context.ConnectionId, out var user);
await Clients.All.SendAsync("UserLeft", user);
await base.OnDisconnectedAsync(ex);
}
private string GetUserName() =>
Context.User?.Identity?.Name ?? Context.ConnectionId;Автоматическое переподключение
Включите автоматическое переподключение на клиенте, чтобы корректно обрабатывать временные разрывы соединения. Задержки между повторными попытками можно настроить.
// JavaScript client
const conn = new signalR.HubConnectionBuilder()
.withUrl("/hubs/chat")
.withAutomaticReconnect([0, 2000, 5000, 10000, 30000]) // retry delays in ms
.build();
conn.onreconnecting(err => console.warn("Reconnecting...", err));
conn.onreconnected(id => console.log("Reconnected:", id));
conn.onclose(err => console.error("Disconnected:", err));Аутентификация с помощью SignalR
SignalR учитывает промежуточное ПО аутентификации ASP.NET Core. Добавьте [Authorize] к классу хаба или используйте обработчик JWT, поддерживающий токены в строке запроса (это необходимо для аутентификации через WebSocket).
[Authorize]
public class PrivateHub : Hub
{
public Task SendMessage(string msg)
{
var user = Context.User!.Identity!.Name;
return Clients.All.SendAsync("Msg", user, msg);
}
}
// JWT via query string (WebSocket requirement):
builder.Services.AddAuthentication().AddJwtBearer(opt =>
{
opt.Events = new JwtBearerEvents
{
OnMessageReceived = ctx =>
{
var token = ctx.Request.Query["access_token"];
if (!string.IsNullOrEmpty(token))
ctx.Token = token;
return Task.CompletedTask;
}
};
});Быстрая проверка
Как отправить сообщение SignalR из фоновой службы, находящейся вне класса хаба?
Итоги: хабы и соединения SignalR
Основные выводы:
- SignalR автоматически выбирает лучший транспорт (WebSockets, SSE, длинный опрос)
- Методы хаба можно вызывать из клиентов;
Clients.*выбирает определённых получателей - Внедряйте
IHubContext<T>, чтобы отправлять сообщения вне хаба - Переопределяйте
OnConnectedAsync/OnDisconnectedAsyncдля управления жизненным циклом - Используйте
withAutomaticReconnect()для устойчивых соединений клиента - Для соединений WebSocket требуется аутентификация JWT через строку запроса
Часто задаваемые вопросы
Урок «Центры и подключения SignalR» бесплатный?
Да — полный текст урока «Центры и подключения SignalR» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс C# Academy, подпишись на CoddyKit PRO. Курс C# Academy содержит 4 уроков всего.
Чему я научусь в уроке «Центры и подключения SignalR»?
Создайте центр SignalR, подключите его в ASP.NET Core и установите соединения WebSocket из клиентов JavaScript и .NET. Ты практикуешь C# Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать C# Academy?
Предыдущий опыт не требуется. C# Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 1 из 4.
Сколько времени занимает урок «Центры и подключения SignalR»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке C# Academy?
Да. Каждый урок C# Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Центры и подключения SignalR
- Группы, пользователи и управление подключениями
- Строго типизированные центры
- Масштабирование с помощью Redis Backplane