TGViewer
.NET Разработчик .NET Разработчик @netdeveloperdiary · 6.75K subscribers
Post #3031 2.61K
День 2519. #ЗаметкиНаПолях
Разбираем Server-Sent Events в
ASP.NET Core и .NET 10. Начало
Обновления UI в реальном времени больше не являются "желательной" функцией. Большинство современных приложений ожидают потоков данных в реальном времени от сервера. В течение многих лет основным решением в экосистеме .NET был SignalR. Хотя он невероятно мощный, приятно иметь другие варианты для более простых сценариев использования.

В ASP.NET Core 10 появился собственный высокоуровневый API для событий, отправляемых сервером (SSE). Он устраняет разрыв между базовым HTTP-опросом и полнодуплексными WebSockets через SignalR.

Зачем?
SignalR — мощный инструмент, который автоматически обрабатывает WebSockets, Long Polling и SSE, обеспечивая полнодуплексный (двусторонний) канал связи. Однако это сопряжено с определёнными затратами: специфический протокол, необходимость в клиентской библиотеке и потребность в «липких сессиях» или бэкэнде (например, Redis) для масштабирования.

В отличие от SignalR, SSE:
- Однонаправленные - разработаны специально для потоковой передачи данных с сервера на клиент.
- Нативны для HTTP - это стандартный HTTP-запрос с типом содержимого text/event-stream. Никаких пользовательских протоколов.
- Поддерживают автоматическое переподключение - браузеры обрабатывают переподключения напрямую через API EventSource.
- Легковесны - нет тяжёлых клиентских библиотек или сложной логики рукопожатия.

Простейшая конечная точка SSE
Мы можем использовать новый объект Results.ServerSentEvents для возврата потока событий из любого IAsyncEnumerable<T>. Поскольку IAsyncEnumerable представляет собой поток данных, который может поступать с течением времени, сервер знает, что нужно поддерживать HTTP-соединение открытым, а не закрывать его после первого «фрагмента» данных.

Вот минимальный пример конечной точки SSE, которая передаёт информацию о размещении заказов в режиме реального времени:
app.MapGet("orders/realtime", (
ChannelReader<OrderPlacement> reader,
CancellationToken ct) =>
{
// ReadAllAsync возвращает IAsyncEnumerable
// Results.ServerSentEvents заставляет браузер держать подключение открытым
// Новые данные передаются клиенту по мере поступления из канала
return Results.ServerSentEvents(
reader.ReadAllAsync(ct),
eventType: "orders");
});

Когда клиент обращается к этой конечной точке:
- Сервер отправляет заголовок Content-Type: text/event-stream.
- Соединение остается активным в состоянии ожидания данных.
- Как только приложение отправляет заказ в канал, IAsyncEnumerable возвращает этот элемент, и .NET немедленно отправляет его по открытому HTTP-каналу в браузер.
Это невероятно эффективный способ обработки «push»-уведомлений без накладных расходов, связанных с протоколом с сохранением состояния.

В этом примере используется канал. В реальном приложении у вас может быть фоновый сервис, прослушивающий очередь сообщений (например, RabbitMQ или Azure Service Bus) или канал изменений БД и отправляющий новые события в канал для обработки подключёнными клиентами.

Продолжение следует…

Источник:
https://www.milanjovanovic.tech/blog/server-sent-events-in-aspnetcore-and-dotnet-10
  • 👍 25
More from @netdeveloperdiary
  1. Sep 29, 2026Фото 3 (с) Анатолий Кулаков
  2. Sep 29, 2026День 2799. Конференция DotNext 2026. Часть 1 25 и 26 сентября в Москве прошла очередная ко…
  3. Sep 28, 2026День 2798. #Оффтоп Утиная Типизация в C# с Помощью Перехватчиков. Часть 2 Некоторое время…
  4. Sep 27, 2026День 2797. #ЗаметкиНаПолях #AI Рабочий процесс с Copilot для .NET. Окончание Начало Продол…
  5. Sep 26, 2026День 2796. #ЗаметкиНаПолях #AI Рабочий процесс с Copilot для .NET. Продолжение Начало Три…
  6. Sep 25, 2026День 2795. #ЗаметкиНаПолях #AI Рабочий процесс с Copilot для .NET. Начало Проблема с позиц…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →