Вы всё ещё обновляете страницу вручную? Пора переходить в реальное время
Представьте: вы открыли онлайн-биржу, а курс доллара намертво застыл. Вы жмёте 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-ответ, но с ос