WebFlux SSE (Події, надіслані сервером) — Відстеження прогресу в реальному часі за допомогою WebFlux SSE та Quartz Jobs

pic

Живий приклад

Привіт, друзі! Я знову з вами!

Після того, як я поринув у тему 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 може вирішити цю проблему, дозволяючи серверу передавати оновлення прогресу клієнту в реальному часі.

Для демонстрації я створив простий додаток з двома кінцевими точками:

  1. Кінцева точка для запуску завдання: Ця точка динамічно запускає завдання Quartz.
  2. Кінцева точка для прогресу: Ця точка транслює оновлення прогресу завдання 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"}

pic

Живий приклад

Приклад коду доступний на моєму 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

Leave a Reply

Your email address will not be published. Required fields are marked *