Открыть сервис

Long Polling

Long Polling — это технология, используемая в веб-разработке для организации серверного «толчка» (push-уведомлений) и получения данных в реальном времени. В отличие от традиционного периодического опроса (polling), где клиент отправляет запросы через фиксированные интервалы, long polling позволяет серверу удерживать соединение открытым до тех пор, пока не появится новое сообщение или не истечёт тайм-аут. После получения ответа клиент немедленно инициирует новый запрос, создавая эффект непрерывного обновления данных.

История

Идея long polling возникла как эволюция классического polling (опрос) в начале 2000-х годов, когда веб-приложения начали требовать более оперативного обновления контента, чем это позволяли периодические запросы. Технология стала популярной с развитием AJAX (Asynchronous JavaScript and XML), который позволил выполнять асинхронные HTTP-запросы без перезагрузки страницы.

Первые реализации long polling появились в таких продуктах, как Google Talk (около 2005 года) и серверных решениях для чатов. В 2006 году технология была описана в спецификации BOSH (Bidirectional-streams Over Synchronous HTTP), которая стала основой для протоколов XMPP. С появлением WebSocket (стандартизирован в 2011 году) long polling утратил часть популярности, но остаётся востребованным в средах, где WebSocket недоступен (например, за прокси-серверами или в старых браузерах).

Принцип работы

Классический polling

При обычном опросе клиент отправляет HTTP-запросы через равные промежутки времени (например, каждые 5 секунд). Сервер немедленно возвращает ответ, даже если новых данных нет. Это приводит к избыточной нагрузке на сеть и сервер, особенно при большом количестве клиентов.

Long polling

  1. Клиент отправляет HTTP-запрос на сервер.
  2. Сервер не отвечает сразу, если нет новых данных, а удерживает соединение открытым.
  3. Когда появляется новое сообщение или событие, сервер возвращает ответ с данными.
  4. Клиент обрабатывает ответ и немедленно отправляет новый запрос.
  5. Если в течение заданного времени (тайм-аута) данные не появились, сервер возвращает пустой ответ или специальный сигнал. Клиент после этого снова инициирует запрос.

Таким образом, сервер «толкает» данные клиенту, а клиент всегда поддерживает одно активное соединение. Тайм-аут обычно устанавливается в диапазоне от 30 до 120 секунд, чтобы избежать разрыва соединения из-за сетевых ограничений.

Виды и реализации

Долгий опрос (Long Polling)

Стандартная реализация, описанная выше. Используется в большинстве приложений, где требуется псевдо-реальное время.

Асинхронный long polling

Сервер обрабатывает запросы асинхронно, не блокируя поток выполнения. Это позволяет обслуживать большое количество одновременных соединений без значительного увеличения потребления ресурсов. Реализуется с помощью таких технологий, как Node.js, EventMachine (Ruby), Twisted (Python) или асинхронных воркеров в Java (Servlet 3.0+).

Long polling с тайм-аутом

Вариант, при котором сервер принудительно закрывает соединение через определённый интервал, даже если данные не появились. Это необходимо для предотвращения зависания соединений при сбоях сети или перезагрузке сервера.

Устройство и характеристики

Требования к серверу

Требования к клиенту

Производительность

Применение

Long polling широко используется в веб-приложениях, где требуется обновление данных в реальном времени, но нет возможности или необходимости использовать WebSocket. Основные области применения:

Примеры реализации

На JavaScript (Node.js с Express)

```javascript const express = require('express'); const app = express();

app.get('/poll', (req, res) => { // Удерживаем соединение до появления нового сообщения waitForMessage((message) => { res.json({ data: message }); }); });

function waitForMessage(callback) { // Имитация ожидания нового сообщения setTimeout(() => { callback('Новое сообщение'); }, 5000); }

app.listen(3000); ```

На Python (Flask)

```python from flask import Flask, jsonify, request import time

app = Flask(__name__)

@app.route('/poll') def poll():

Ожидание нового события

message = wait_for_message() return jsonify({'data': message})

def wait_for_message():

Имитация ожидания

time.sleep(5) return 'Новое сообщение'

if __name__ == '__main__': app.run() ```

Критика и ограничения

Сравнение с альтернативами

ТехнологияЗадержкаДвунаправленностьПоддержка браузерамиНагрузка на сервер
Long pollingСредняя (1–5 сек)НетВсеВысокая
WebSocketНизкая (< 100 мс)ДаСовременныеНизкая
Server-Sent Events (SSE)НизкаяНет (только от сервера)СовременныеСредняя
Polling (классический)Высокая (зависит от интервала)НетВсеОчень высокая

Интересные факты

Источники

BFOmetr — база данных и аналитика по компаниям России.

На главную BFOmetr →