Примеры таких ситуаций:
🔵Разовое уведомление: пользователь запросил формирование отчета, отчет формируется на бэке какое-то время. По готовности отчета бэк должен сообщить фронту, что отчет готов.
🔵Лента комментариев: пользователь смотрит стрим, хочет читать новые комментарии к видео без перезагрузки страницы (комментарии должны приходить с бэка, так как их оставляют другие пользователи).
🔵 Пользователь общается со службой поддержки в чате на сайте, нужно присылать в чат ответы поддержки.
Давайте разберем какие есть варианты, в чем их ключевые отличия и для какой ситуации подойдет каждый из вариантов.
1️⃣ Polling
Фронт периодически спрашивает бэк, не появилось ли событие.
Обычный HTTP/HTTPS запрос типа
GET /status/{taskId} например раз в 5 секунд.Бэк обычно отвечает статусом:
PROCESSING/SUCCESS/ERRORПока приходит PROCESSING — ждем, когда в ответ на запрос фронта придет SUCCESS, можно по отдельному эндпойнту запросить результат обработки.
Аналогия из времен, когда мы общались по телефону. Представьте, что вы заказали у бухгалтерии какой-то отчет.
Вы звоните им каждые 5 секунд:
— Отчёт готов?
— Нет.
Через 5 секунд снова:
— Отчёт готов?
— Нет.
Затем:
— Отчёт готов?
— Да.
Вы кладёте трубку и идете в бухгалтерию за отчетом.
Плюсы:
➕ быстро и легко реализовать
➕ нет висящих долго соединений
Минусы:
➖ очень много лишних запросов (пока отчет не готов) — лишняя нагрузка на сервер
➖ задержка: оповещение о событии с бэка не в real-time, а зависит от периодичности опроса
Это вариант подходит, когда нужна простая схема, события редкие, пользователей мало, SLA по "мгновенности" не критичен (задержка в 5–30 сек — это ок). Например, как раз для случая с уведомлением о готовности отчета, если у вас не много пользователей.
Если кто-то скажет, что такое уже не используется — не верьте, я сталкивалась. Вполне используется, если нагрузка маленькая и нет нужды заморачиваться с SSE (о нем ниже).
2️⃣ Long Polling
Фронт делает HTTP запрос, а сервер не отдает ответ сразу, а держит соединение открытым до события или истечения таймаута. Когда событие произошло, сервер отвечает в рамках этого соединения и закрывает его. Для получения следующего события нужно открывать новое соединение.
Вернемся к аналогии с телефонными звонками.
Вы звоните в бухгалтерию:
— Отчёт готов?
Они молчат. Вы молчите и ждете.
Через 30 секунд соединение обрывается (таймаут).
Вы перезваниваете:
— Отчёт готов?
Они молчат. Вы молчите и ждете.
Затем они говорят:
— Да, отчет готов.
Вы кладёте трубку.
Вспоминаете, что хотели узнать еще про справку 2НДФЛ. Снова звоните, все повторяется.
📎Отличие от polling: вы не перезваниваете каждые 5 секунд, а ждете до истечения таймаута соединения, но соединение все равно регулярно пересоздается.
Плюсы:
➕ почти real-time без сложностей с настройкой SSE/WebSocket
Минусы:
➖ нагрузка на сервер из-за долго висящий соединений
➖ нагрузка из-за переподключений после таймаута
Продолжение ⬇️