Polling и long-polling: первые костыли

Первые способы изобразить «живые» данные поверх обычного HTTP — и их цена.

Polling (опрос) — приём, при котором браузер сам периодически спрашивает сервер «есть новости?», имитируя инициативу сервера частыми запросами.

Короткий polling

Самая прямолинейная идея: раз сервер не может заговорить первым — пусть браузер спрашивает его снова и снова. Каждые пару секунд шлём запрос: «появились новые сообщения?». Если да — показываем, если нет — ждём и спрашиваем опять.

каждые 3 секунды:
  Браузер  -- GET /messages?after=42 -->  Сервер
  Браузер  <-- 200 [] (пусто) ----------  Сервер
  ... ждём 3 сек ...
  Браузер  -- GET /messages?after=42 -->  Сервер
  Браузер  <-- 200 [сообщение 43] ------  Сервер

Работает, но плохо. Задержка — до интервала опроса (в среднем половина). Большинство запросов возвращают пустоту — это лишний трафик, нагрузка на сервер и батарею телефона. Уменьшишь интервал ради скорости — вырастет нагрузка; увеличишь ради экономии — вырастет задержка.

Long-polling (длинный опрос)

Умнее: браузер шлёт запрос, а сервер не отвечает сразу, если новостей нет — он держит соединение открытым и ждёт. Как только появляется событие — сразу отвечает. Браузер, получив ответ, тут же шлёт новый запрос.

Браузер  -- GET /messages?after=42 -->  Сервер
         (сервер держит, ждёт события...)
         ... через 8 секунд приходит сообщение 43 ...
Браузер  <-- 200 [сообщение 43] ------  Сервер
Браузер  -- GET /messages?after=43 -->  Сервер  (сразу новый запрос)

Так задержка почти исчезает: сервер отвечает в момент события, а не по таймеру. Пустых ответов почти нет. Это уже близко к настоящему реалтайму.

Как работает под капотом

Long-polling эксплуатирует то, что сервер вправе отвечать на запрос сколь угодно долго. Пока ответ не пришёл, TCP-соединение живёт. Но это всё ещё один запрос — один ответ: после каждого ответа цикл начинается заново, с новыми заголовками и накладными расходами. И для каждого клиента сервер вынужден держать «висящее» соединение, что съедает ресурсы при тысячах пользователей.

Частые ошибки

  • Делать интервал короткого polling в 200 мс «ради скорости». Это лавина запросов; сервер ляжет под нагрузкой.
  • Не ставить таймаут на long-polling. Прокси и балансировщики рвут «молчащие» соединения; нужен периодический ответ-пустышка (например, раз в 25 секунд).
  • Считать long-polling полноценным двусторонним каналом. Это по-прежнему серия HTTP-запросов клиента, а не один открытый канал.

Итоги

  • Короткий polling — частые запросы по таймеру: просто, но с задержкой и лишним трафиком.
  • Long-polling — сервер держит запрос открытым до события: задержка почти нулевая.
  • Оба приёма остаются в рамках «запрос — ответ» и масштабируются плохо.
  • Это переходные решения на пути к настоящему постоянному каналу.
Проверьте себя
1. Чем long-polling отличается от короткого polling?
AСервер сразу отвечает пустотой, если новостей нет
BСервер держит запрос открытым и отвечает в момент появления события
CБраузер вообще не шлёт запросов
DИспользуется отдельный TCP-порт
2. Главный минус короткого polling — это:
AНевозможность передавать JSON
BЗадержка и лишний трафик от пустых ответов
CОтсутствие шифрования
DНесовместимость с мобильными браузерами