Порівняння підходів: Як вибрати правильну технологію нотифікацій
Порівняння підходів: Як вибрати правильну технологію нотифікацій
Ви пройшли довгий шлях: від простої таблиці в базі даних до Web Push і Email. Кожен підхід вирішував специфічну проблему попереднього — і кожен має свою оптимальну нішу.
Але як вибрати правильний підхід у реальному проєкті? Саме цьому присвячена фінальна стаття.
Повна порівняльна таблиця
| Характеристика | БД Notifications | Short Polling | Long Polling | SSE | WebSockets | SignalR | Web Push | |
|---|---|---|---|---|---|---|---|---|
| Модель | Pull | Pull | Pull | Push | Push | Push | Push | Push |
| Затримка | Manual | До N сек | < 2 сек | < 1 сек | < 100 мс | < 100 мс | Залежить від ОС | Хвилини |
| З'єднань | 0 | N (нові) | N (утрим.) | 1 | 1 | 1 | 0 | 0 |
| Напрямок | Client pull | → | → | ← | ↔ | ↔ | ← | ← |
| Офлайн доставка | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ✅ |
| Без браузера | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ✅ |
| Складність | ★☆☆☆ | ★☆☆☆ | ★★☆☆ | ★★☆☆ | ★★★☆ | ★★☆☆ | ★★★★ | ★★☆☆ |
| Масштабування | ✅ Просте | ✅ Просте | ⚠️ Складніше | ⚠️ Складніше | ⚠️ Складніше | ⚠️ Redis backplane | ✅ Просте | ✅ Просте |
| Підходить для | Архів | Рідкі оновлення | Рідкі + своєчасні | Сервер→клієнт | Чат, ігри | Будь-який real-time | Офлайн-доставка | Важливі події |
Decision Tree: Дерево вибору
Сценарії реальних застосунків
Різні нотифікації вимагають різних підходів:
| Нотифікація | Рекомендований підхід | Чому |
|---|---|---|
| Лічильник у «дзвонику» | SSE | Один канал, лише оновлення числа |
| Список нотифікацій | БД Notifications | Читається при відкритті панелі |
| Нові повідомлення в чаті | SignalR або WebSockets | Двосторонній чат |
| Push коли застосунок закрито | Web Push | Офлайн-доставка |
| Тижневий дайджест | Регулярне зведення активності |
| Нотифікація | Рекомендований підхід | Чому |
|---|---|---|
| Зміна статусу замовлення | Email + Web Push | Критично важливо, потрібна офлайн-доставка |
| Підтвердження оплати | Юридичний підтверджуючий документ | |
| «Товар знову в наявності» | Email або Web Push | Офлайн-доставка важлива |
| Відстеження доставки | SSE або Short Polling | Оновлення рідко (раз на годину) |
| Онлайн чат з підтримкою | SignalR | Двосторонній real-time |
| Нотифікація | Рекомендований підхід | Чому |
|---|---|---|
| Метрики реального часу | SSE | Один потік даних від сервера |
| Алерти про перевищення порогу | Web Push + Email | Критично + офлайн |
| Спільна робота в документі | SignalR | Двосторонній real-time |
| Щоденний звіт | Регулярна доставка | |
| Статус фонових задач | SSE або Long Polling | Рідкісні оновлення |
| Нотифікація | Рекомендований підхід | Чому |
|---|---|---|
| Ігрові події (< 100мс) | WebSockets (або SignalR) | Мінімальна затримка, двосторонній |
| Запрошення в гру (офлайн) | Web Push | Офлайн-доставка |
| Підсумки бою, досягнення | Красивий звіт не поспішає |
Комбінування підходів
У реальних застосунках один засіб рідко є достатнім. Типова комбінація:
Система нотифікацій реального застосунку:
┌────────────────────────────────────────────┐
│ БД Notifications (завжди) │
│ ├── SSE/SignalR (онлайн real-time) │
│ ├── Web Push (офлайн браузерний) │
│ └── Email (важливі події / дайджести) │
└────────────────────────────────────────────┘
- Нотифікація завжди зберігається в БД — це єдине джерело правди
- Якщо клієнт онлайн — SSE або SignalR доставляє миттєво
- Якщо клієнт офлайн — Web Push або Email через фоновий сервіс
Антипатерни та типові помилки
Проблема: setInterval(check, 1000) для 10 000 користувачів = 10 000 запит/сек
Вирішення: SSE або SignalR — один відкритий канал замість N запитів
Проблема: await emailSender.SendAsync() всередині MapPost() блокує відповідь на 1-5 сек
Вирішення: Поставити Email у Channel<T> чергу → відповісти 202 Accepted
Проблема: Singleton-сервіс тримає один DbContext весь час — memory leak, stale кеш
Вирішення: IServiceScopeFactory.CreateAsyncScope() для кожної операції
Проблема: Мережа обірвалася → WebSocket закрився → клієнт більше не отримує повідомлень
Вирішення: Використовуйте SignalR (.withAutomaticReconnect()) або реалізуйте reconnect вручну
Проблема: Ключ у репозиторії → зловмисники можуть надсилати push від вашого імені
Вирішення: Environment variables або .NET Secret Manager
Що далі
Ви освоїли весь спектр технологій нотифікацій — від простого Pull Model до push-сповіщень у фоні. Для поглиблення рекомендується:
Підсумок модуля
Ви пройшли повний курс нотифікацій у вебі:
| # | Стаття | Ключова ідея |
|---|---|---|
| 01 | БД нотифікації | Pull Model — нотифікація як запис у таблиці |
| 02 | Polling | Автоматичне опитування через setInterval |
| 03 | SSE | Постійний канал push від сервера через Channel<T> |
| 04 | WebSockets | Повнодуплексний real-time зв'язок |
| 05 | SignalR | Абстракція над транспортами з Hub і Groups |
| 06 | Background Services | IHostedService, BackgroundService, черги задач |
| 07 | Web Push | Офлайн push через Push Service + VAPID |
| 08 | Надійний зовнішній канал з MailKit та чергою | |
| 09 | Порівняння | Decision tree та антипатерни |
Головний принцип, що пронизує весь модуль: правильний інструмент для правильної задачі. Немає єдиного «найкращого» рішення — є рішення, що оптимально відповідає конкретним вимогам вашого застосунку.
Email нотифікації
Вивчаємо email як надійний зовнішній канал для важливих нотифікацій. Реалізуємо відправку через MailKit, HTML-шаблони, абстракцію IEmailSender та чергу на базі Channel<T>.
Hangfire: Надійне планування фонових задач
Детальний розгляд Hangfire — бібліотеки для надійного планування та виконання фонових задач у .NET. Fire-and-forget, delayed, recurring задачі, Dashboard, Storage, Retry-механізм, черги, інтеграція з ASP.NET Core DI.