Long-Polling, WebSockets, SSE и Comet: Полный разбор с кодом на PHP

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Вы всё ещё обновляете страницу вручную? Пора переходить в реальное время

Представьте: вы открыли онлайн-биржу, а курс доллара намертво застыл. Вы жмёте F5, жмёте — а он не меняется. Знакомо? А теперь представьте, что курс обновляется сам, как в кино — плавно и без задержек. Это не магия, это технологии реального времени. Именно они превращают статичный сайт в живой организм: чаты, уведомления, дашборды с обновлением в реальном времени.

Сегодня мы разберём четыре кита, на которых держится весь real-time веб: Long-Polling, WebSockets, Server-Sent Events (SSE) и Comet. Я покажу, как они работают «под капотом», и дам готовый код на PHP, который вы сможете использовать прямо сейчас. Поехали!

Статья написана для образовательного портала pythonlib.ru — здесь мы превращаем сложные концепции в понятные инструменты.

Коротко о главном: что скрывается за терминами?

Когда вы открываете обычную страницу, браузер делает запрос, сервер отвечает — соединение закрыто. Всё просто. Но что, если сервер хочет сам «постучаться» к вам с новыми данными? Тут и начинаются танцы с бубном.

  • Long-Polling (Длинный опрос) — старый, но надёжный дедушка. Клиент «висит» на сервере и ждёт, когда тот соизволит ответить.
  • WebSockets (Вебсокеты) — тренд последних лет. Полноценный двухсторонний канал, как телефонная линия.
  • Server-Sent Events (SSE) — односторонняя трансляция от сервера к клиенту. Идеально для новостных лент и котировок.
  • Comet — общее название для техник, когда сервер «проталкивает» данные клиенту без дополнительного запроса. Long-Polling и SSE — частные случаи Comet.

Технология №1: Long-Polling — дедушка real-time

Long-Polling — это когда клиент говорит серверу: «Я подожду, сколько нужно, только ответь, когда появятся данные». Клиент открывает соединение и держит его открытым, пока сервер не пришлёт ответ. После получения ответа клиент сразу же создаёт новый запрос. Получается бесконечная цепочка.

Плюсы: работает на любом хостинге, не требует дополнительных библиотек, поддерживается всеми браузерами.

Минусы: много лишних заголовков, нагрузка на сервер, задержки при большом количестве клиентов.

Пример на PHP (Long-Polling)

<?php
// long_polling.php
header('Content-Type: text/plain; charset=utf-8');
header('Cache-Control: no-cache');

$timeout = 30; // ждём максимум 30 секунд
$start = time();

// Эмулируем появление новых данных
$data = getNewDataFromDB(); // ваша функция получения данных

while (empty($data)) {
    if ((time() - $start) > $timeout) {
        echo json_encode(['status' => 'timeout', 'data' => null]);
        flush();
        exit;
    }
    usleep(500000); // спим 0.5 секунды
    $data = getNewDataFromDB();
}

echo json_encode(['status' => 'ok', 'data' => $data]);
flush();
?>

На клиенте (JavaScript) это будет выглядеть так:

function longPoll() {
    fetch('/long_polling.php')
        .then(response => response.json())
        .then(data => {
            if (data.status === 'ok') {
                console.log('Новые данные:', data.data);
                // обновляем интерфейс
            }
            longPoll(); // сразу создаём новый запрос
        })
        .catch(error => {
            console.error('Ошибка:', error);
            setTimeout(longPoll, 1000); // переподключаемся через секунду
        });
}
longPoll();

Видите? Клиент висит, ждёт, получает данные — и снова вешается. Это и есть Long-Polling на PHP в чистом виде.

Технология №2: WebSockets — двухсторонняя магистраль

WebSockets — это как открытая дверь между браузером и сервером. После рукопожатия (handshake) соединение остаётся открытым, и обе стороны могут отправлять данные в любой момент. Никаких заголовков, никаких лишних запросов — только чистые данные.

Плюсы: минимальная задержка (латенси), низкий трафик, настоящий real-time.

Минусы: нужен специальный сервер (обычно на Node.js или Ratchet для PHP), сложнее в настройке, не все прокси умеют проксировать WebSockets.

Пример на PHP (WebSocket сервер с библиотекой Ratchet)

Для работы с WebSockets в PHP лучше всего использовать библиотеку Ratchet. Установите её через Composer: composer require cboden/ratchet.

<?php
// server.php
use Ratchet\MessageComponentInterface;
use Ratchet\ConnectionInterface;
use Ratchet\Server\IoServer;
use Ratchet\Http\HttpServer;
use Ratchet\WebSocket\WsServer;

require __DIR__ . '/vendor/autoload.php';

class WebSocketServer implements MessageComponentInterface {
    protected $clients;

    public function __construct() {
        $this->clients = new \SplObjectStorage;
    }

    public function onOpen(ConnectionInterface $conn) {
        $this->clients->attach($conn);
        echo "Новое подключение: {$conn->resourceId}\n";
    }

    public function onMessage(ConnectionInterface $from, $msg) {
        echo "Получено сообщение: $msg\n";
        // Отправляем всем клиентам
        foreach ($this->clients as $client) {
            if ($from !== $client) {
                $client->send($msg);
            }
        }
    }

    public function onClose(ConnectionInterface $conn) {
        $this->clients->detach($conn);
        echo "Соединение закрыто: {$conn->resourceId}\n";
    }

    public function onError(ConnectionInterface $conn, \Exception $e) {
        echo "Ошибка: {$e->getMessage()}\n";
        $conn->close();
    }
}

// Запускаем сервер на порту 8080
$server = IoServer::factory(
    new HttpServer(
        new WsServer(
            new WebSocketServer()
        )
    ),
    8080
);

$server->run();

Запускаем сервер: php server.php. Теперь он слушает порт 8080 и готов принимать подключения. WebSockets PHP в действии — просто и элегантно.

Технология №3: Server-Sent Events (SSE) — односторонний ручеёк

SSE — это когда сервер может отправлять данные клиенту, но клиент не может отправить данные обратно (кроме обычных HTTP-запросов). Технически это обычный HTTP-ответ, но с ос

Блоги

Рекомендаций по книгам