Живий приклад
Привіт, друзі! Я знову з вами!
Після того, як я поринув у тему Java 21 Virtual Threads vs Reactive Streams у своїй попередній статті, я повернувся з новою захоплюючою темою, яка обов'язково приверне вашу увагу. Цього разу ми зануримемося в щось справді динамічне та інтерактивне — Оновлення прогресу в реальному часі за допомогою WebFlux SSE та Quartz Jobs.
Якщо ви коли-небудь працювали з довготривалими завданнями, такими як завантаження файлів, обробка даних або генерація звітів у веб-додатках, ви знаєте, яке це випробування — надавати користувачам реальний зворотний зв'язок. Зазвичай користувачі змушені здогадуватися про прогрес цих завдань, що призводить до постійного оновлення сторінки або безкінечного очікування оновлень. Але що, якщо існує кращий спосіб?
У цій статті ми дізнаємося, як інтегрувати Server-Sent Events (SSE) з Spring WebFlux і використовувати Quartz для динамічного планування завдань, щоб транслювати оновлення прогресу в реальному часі безпосередньо до клієнта. Уявіть, що ви надсилаєте динамічні прогрес-бари, оновлення статусу в реальному часі і багато іншого — все без необхідності опитування або вручну оновлювати сторінку.
Розуміння WebFlux SSE
WebFlux SSE — це реактивне розширення для надсилання подій, ініційованих сервером, клієнту через HTTP. Воно побудовано на реактивній основі Spring WebFlux і дозволяє серверу надсилати оновлення клієнту асинхронно, без блокування. SSE є чудовим вибором для додатків, де необхідні оновлення в реальному часі, таких як живі інформаційні панелі, прогрес-бари та системи сповіщень.
Чому Quartz Jobs?
Quartz — потужна бібліотека для планування завдань, яка надає розширені можливості для Java-додатків. Вона може використовуватися для періодичного виконання завдань або для їх виконання у фоновому режимі. У нашому випадку ми хочемо відслідковувати прогрес завдання Quartz і надсилати оновлення клієнту по мірі виконання цього завдання.
Проблема
Припустимо, у нас є довготривале завдання Quartz, таке як обробка файлів або складні обчислення. Однак клієнт не знає прогресу цього завдання, поки воно не буде завершено. WebFlux SSE може вирішити цю проблему, дозволяючи серверу передавати оновлення прогресу клієнту в реальному часі.
Для демонстрації я створив простий додаток з двома кінцевими точками:
- Кінцева точка для запуску завдання: Ця точка динамічно запускає завдання Quartz.
- Кінцева точка для прогресу: Ця точка транслює оновлення прогресу завдання Quartz у реальному часі за допомогою WebFlux SSE.
Ця кінцева точка створює і запускає завдання Quartz, повертаючи ідентифікатор завдання в відповіді:
/api/v1/job/create
{
"id": 36,
"jobName": "my-job-36",
"jobProgress": 0,
"jobStatus": "IN-PROGRESS"
}
Ця кінцева точка транслює реальний прогрес завдання:
/api/v1/job/{jobId}/progress
id:45
event:progress-update
data:{"id":45,"jobName":null,"jobGroup":null,"jobDescription":null,"jobProgress":1.0,"jobStatus":"IN-PROGRESS"}
Живий приклад
Приклад коду доступний на моєму GitHub
https://github.com/its-me-gayan/WebfluxSSEQuartzExample.git
Альтернативні підходи: SSE, Flux та WebSocket
Хоча в цій статті основна увага приділяється використанню WebFlux SSE з Quartz Jobs для надання оновлень прогресу в реальному часі, варто зазначити, що є й інші підходи для досягнення подібної функціональності. Давайте розглянемо, як SSE, Flux і WebSocket порівнюються:
1. Server-Sent Events (SSE)
SSE — природний вибір для однонаправлених оновлень від сервера до клієнта. Вона добре підходить для таких сценаріїв, як інформаційні панелі в реальному часі, відстеження прогресу та сповіщення. Її простота і вбудована підтримка в браузерах роблять її кращим варіантом, коли двостороння комунікація не потрібна.
2.
Reactive Streams з Flux
Якщо ви вже використовуєте Spring WebFlux, використання Flux
для реактивних потоків є ще одним потужним варіантом. За допомогою Flux
ви можете транслювати оновлення безпосередньо до клієнта асинхронно і без блокування. Воно безшовно інтегрується з WebFlux SSE та дозволяє відправляти дані через регулярні інтервали або на основі прогресу завдання Quartz.
Приклад інтеграції Flux:
@GetMapping(value = "/progress", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public Flux getJobProgress() {
return jobService.getProgressUpdates();
}
3. WebSocket
Для більш складних сценаріїв, які вимагають двосторонньої комунікації (наприклад, чат в реальному часі, ігри або колаборативні додатки), WebSocket є кращим варіантом. WebSocket встановлює постійну, двосторонню зв'язок між сервером та клієнтом, дозволяючи обом сторонам надсилати та отримувати дані в реальному часі.
Приклад використання WebSocket:
- Клієнт може надсилати запити на конкретні оновлення, і сервер може динамічно відповідати.
- Користувачі можуть отримувати оновлення прогресу, одночасно надсилаючи запити на скасування або паузу.
Який підхід вибрати?
Зрозумівши переваги кожної технології, ви зможете вирішити, який підхід найкраще відповідає вашим вимогам. Для однонаправлених оновлень, таких як відстеження прогресу, SSE та Flux є ефективними рішеннями, тоді як для інтерактивної двосторонньої комунікації найкращим варіантом буде WebSocket.
Висновок
З WebFlux SSE та Quartz ви можете забезпечити користувачів безперебійними оновленнями в реальному часі для довготривалих завдань. Цей підхід покращує досвід користувача та усуває необхідність постійного оновлення сторінки або опитування.
Сподіваюся, що ця стаття допоможе вам реалізувати динамічне відстеження прогресу в реальному часі у ваших додатках. Поділіться своїми думками та використаннями цього підходу!
Перекладено з: WebFlux SSE (Server Send Event) — Real-Time Progress Tracking with WebFlux SSE and Quartz Jobs