Реалтайм: SignalR и SSE
↑ 3.5 Инфраструктура приложения: ошибки, health checks, фоновые задачи · ← Предыдущая
Зачем это на собесе
Выбор между WebSocket, SignalR, SSE и polling по требованиям и масштабированию.
Объяснение
| Технология | Направление | Особенности |
|---|---|---|
| Polling / long polling | клиент → сервер | просто, лишняя нагрузка |
| SSE | сервер → клиент | HTTP, авто-переподключение, только текст |
| WebSocket | двусторонний | низкий уровень, свой протокол сообщений |
| SignalR | двусторонний | абстракция: WebSocket/SSE/long polling, хабы, группы |
public class NotificationsHub : Hub
{
public override async Task OnConnectedAsync()
{
await Groups.AddToGroupAsync(Context.ConnectionId, $"user-{Context.UserIdentifier}");
await base.OnConnectedAsync();
}
}
builder.Services.AddSignalR();
app.MapHub<NotificationsHub>("/hubs/notifications");
// отправка из сервиса
await hub.Clients.Group($"user-{userId}").SendAsync("orderUpdated", dto);Масштабирование
При нескольких инстансах клиенты на разных серверах не видят друг друга: нужен backplane (Redis, Azure SignalR) и sticky sessions либо только WebSocket.
SSE
app.MapGet("/events", (CancellationToken ct) =>
TypedResults.ServerSentEvents(GetEvents(ct), eventType: "tick"));Проще, чем SignalR, если нужен только поток от сервера (уведомления, прогресс).
Нюансы и подводные камни
- Аутентификация WebSocket: токен в query string (для браузерного WebSocket нельзя задать заголовки) — берегите от логирования.
- Лимиты соединений и память: каждое соединение живёт долго.
- Proxy должен поддерживать Upgrade и большие таймауты.
- Сообщения не гарантируют доставку — при переподключении клиент должен запросить пропущенное.
Практика
- Сделайте уведомление о смене статуса заказа через SignalR.
- Добавьте Redis backplane и запустите два инстанса.
- Сравните SSE и SignalR для потока прогресса.
Вопросы с ответами
SignalR или чистый WebSocket?
SignalR даёт хабы, группы, fallback и переподключение; чистый WebSocket — меньше накладных, но всё вручную.
Когда хватит SSE?
Когда нужен только поток от сервера к клиенту.
Как масштабировать SignalR?
Backplane (Redis/Azure SignalR) и корректная настройка балансировщика.