Москва: проверенные б/у ноутбуки с гарантией и проверкой перед оплатой
+7 906 722-94-45

Главная → Статьи → Long polling и webhook: альтернативы realtime

Long polling и webhook: когда realtime без WebSocket/SSE

Альтернативы WebSocket и SSE: long polling для простых realtime-задач, webhook для сервер-сервер коммуникации и критерии выбора транспорта.

Прямой ответ

Long polling и webhook — альтернативы WebSocket/SSE для realtime-задач (WebSocket — SSE — выбор — «realtime без WebSocket» — realtime), но для других сценариев; Long polling (long polling — клиент шлёт запрос, сервер держит открытым, пока нет данных — long polling — «запрос висит, пока нет события» — realtime — как работает: (1) клиент шлёт GET /events (long polling), (2) сервер держит соединение открытым (long polling — «сервер ждёт события» — realtime), (3) событие произошло — сервер отвечает (long polling — «событие → ответ» — realtime), (4) клиент сразу шлёт новый запрос (long polling — «цикл повторяется» — realtime); зачем long polling: простота (обычный HTTP — long polling — «long polling — это HTTP» — realtime — proxy/firewall проходят (long polling — «HTTP — проходят» — realtime), совместимость (все браузеры — long polling — «long polling везде» — realtime — fallback для SSE (SSE — «IE — long polling» — realtime); когда long polling: редкие обновления (раз в минуту — long polling — «polling проще WebSocket» — техдолг), простые случаи (long polling достаточно — long polling — «WebSocket оверхед» — техдолг), fallback (SSE не поддерживается — SSE — «IE — long polling» — realtime); Webhook (webhook — сервер A шлёт HTTP-запрос серверу B при событии — webhook — «событие → HTTP POST» — realtime — как работает: (1) сервер B регистрирует webhook (URL — webhook), (2) событие на сервере A (webhook — «событие произошло» — realtime), (3) сервер A шлёт POST на URL сервера B (webhook — «POST /webhook» — realtime), (4) сервер B обрабатывает (webhook — «webhook обработан» — realtime); зачем webhook: сервер-сервер коммуникация (webhook — «сервер → сервер» — realtime — не клиент-сервер — webhook), интеграции (webhook — «GitHub → ваш сервер» — realtime — «платёжная система → ваш сервер» — webhook), асинхронность (webhook — «не polling, а push» — realtime — «событие → сразу webhook» — webhook); когда webhook: интеграции с внешними сервисами (webhook — «GitHub/Stripe → ваш сервер» — realtime), сервер-сервер события (webhook — «сервис A → сервис B» — микросервисы — webhook), асинхронные уведомления (webhook — «платёж прошёл → webhook» — realtime); когда НЕ long polling/webhook: частые обновления (раз в секунду — WebSocket/SSE лучше — WebSocket — SSE — «long polling для частых» — оверхед — техдолг), клиент-сервер realtime (WebSocket/SSE — WebSocket — SSE — «webhook для клиента» — не работает — webhook); антипаттерны: long polling для частых событий (long polling — «long polling раз в секунду» — WebSocket лучше — WebSocket — техдолг), webhook без retry (webhook — «webhook не дошёл — потерялся» — retry обязателен — retry — webhook), webhook без проверки подписи (webhook — «webhook без подписи» — OWASP — «любой может послать webhook» — проверка подписи обязательна — webhook).

Практика: long polling и webhook в FastAPI

Long polling в FastAPI (long polling: @app.get("/events") async def events(): event = await wait_for_event(timeout=30) if event: return {"data": event} else: return {"data": None} (long polling — «сервер ждёт 30 с» — realtime — «событие или timeout» — long polling); Webhook receiver (webhook: @app.post("/webhook") async def webhook(request: Request): signature = request.headers.get("X-Signature") if not verify_signature(signature, await request.body()): raise HTTPException(401) data = await request.json() process_event(data) return {"status": "ok"} (webhook — «проверка подписи» — OWASP — «webhook без подписи» — уязвимость — webhook); Retry для webhook (webhook — отправитель): for attempt in range(3): try: response = requests.post(webhook_url, json=event, timeout=5) if response.status_code == 200: break except: time.sleep(2 ** attempt) (retry — «retry с exponential backoff» — retry — «webhook не дошёл — повтор» — webhook); Идемпотентность webhook (webhook — получатель): event_id = data["id"] if await event_exists(event_id): return {"status": "duplicate"} await save_event(event_id, data) (идемпотентность — «дубль webhook — игнор» — идемпотентность — «webhook idempotent» — webhook); Мониторинг (метрики: «long polling requests», «webhook deliveries», «webhook failures» — метрики — алерты — алерты — «webhook не доходит» — incident).

Практический сценарий: интеграция с платёжной системой через webhook

Контекст: e-commerce, интеграция с платёжной системой (Stripe/ЮKassa — webhook), боль: как узнать, что платёж прошёл (polling — «проверять статус каждые 5 с» — long polling — оверхед — техдолг); решение — webhook: (1) регистрация webhook (webhook — « — webhook — «при событии — POST на этот URL» — realtime); (2) событие (платёж прошёл — webhook — «платёж прошёл» — realtime); (3) webhook (webhook — Stripe шлёт POST /webhook/stripe (webhook — «событие → webhook» — realtime); (4) проверка подписи (webhook — X-Signature — OWASP — «проверка подписи» — webhook — «без подписи — уязвимость» — OWASP); (5) идемпотентность (идемпотентность — event_id — идемпотентность — «дубль webhook — игнор» — идемпотентность); (6) retry (retry — Stripe ретраит webhook (retry — «webhook не дошёл — повтор» — retry); (7) мониторинг (метрики — «webhook deliveries», «webhook failures» — метрики — алерты — алерты); результат: платёж прошёл → сразу webhook (webhook — «не polling, а push» — realtime — подпись проверена (OWASP — webhook), идемпотентность (идемпотентность — дубли не вредят — идемпотентность), retry (retry — webhook не дошёл — повтор — retry); вывод: webhook решили задачу (интеграция без polling — webhook — ADR — «webhook без подписи/retry» — антипаттерн — техдолг).

FAQ

Long polling против WebSocket/SSE — когда что использовать? Long polling: простой HTTP (long polling — «long polling — это HTTP» — realtime — все браузеры (long polling — «long polling везде» — realtime — редкие обновления (long polling — «раз в минуту» — техдолг); WebSocket: двунаправленный (WebSocket — «WebSocket — чат/игры» — realtime), SSE: однонаправленный (SSE — «SSE — уведомления» — realtime — авто-reconnect (SSE — «SSE сам» — realtime); когда long polling: редкие обновления (long polling — «раз в минуту» — техдолг), fallback (SSE не поддерживается — SSE — «IE — long polling» — realtime), когда WebSocket: чат/игры (WebSocket — «двунаправленный» — realtime), когда SSE: уведомления (SSE — «однонаправленный» — realtime); «long polling для частых» — антипаттерн (WebSocket/SSE лучше — WebSocket — SSE — ADR — техдолг).

Webhook против polling — в чём разница и когда что? Webhook: push (событие → сразу webhook — webhook — «событие → POST» — realtime — сервер-сервер (webhook — «сервер → сервер» — микросервисы); Polling: pull (клиент проверяет — long polling — «клиент → сервер» — realtime — клиент-сервер (long polling — «клиент → сервер» — realtime); когда webhook: интеграции (webhook — «GitHub → ваш сервер» — realtime), сервер-сервер (webhook — «сервис A → сервис B» — микросервисы), когда polling: клиент-сервер (long polling — «клиент → сервер» — realtime), редкие обновления (long polling — «раз в минуту» — техдолг); «webhook для клиента» — не работает (webhook — сервер-сервер — webhook — клиент-сервер — WebSocket/SSE — WebSocket — SSE — ADR — техдолг).

Как обеспечить надёжность webhook? Retry (retry — отправитель ретраит (retry — «webhook не дошёл — повтор» — retry — exponential backoff (retry — «1 с, 2 с, 4 с» — retry); Идемпотентность (идемпотентность — получатель проверяет event_id (идемпотентность — «дубль webhook — игнор» — идемпотентность — «webhook idempotent» — webhook); Проверка подписи (webhook — X-Signature — OWASP — «проверка подписи» — webhook — «без подписи — уязвимость» — OWASP); Мониторинг (метрики — «webhook deliveries», «webhook failures» — метрики — алерты — алерты — «webhook не доходит» — incident); «webhook без retry/идемпотентности» — антипаттерн (webhook не дошёл — потерялся — webhook — retry/идемпотентность обязательны — retry — идемпотентность — ADR — техдолг).

Long polling и webhook — масштабируются ли? Long polling: stateful (соединение держится — long polling — «long polling на сервере» — realtime — sticky sessions (ёмкость — «клиент всегда на сервер 1» — long polling — или pub/sub (Redis — «событие → все серверы» — realtime); Webhook: stateless (HTTP POST — webhook — «webhook — обычный HTTP» — realtime — load balancer распределяет (ёмкость — «webhook проще масштабировать» — webhook); «масштабирование без pub/sub» — long polling не работает (событие на сервере 1 — клиент на сервере 2 не получит — realtime — pub/sub обязателен — Redis — ADR — техдолг).

Источники: Wikipedia (long polling), MDN SSE, W3C webhooks — ссылки в шапке.