Перейти к содержимому

1. Что такое Real-time

Real-time — это когда данные доставляются пользователю немедленно, как только они появляются, без необходимости обновлять страницу вручную.

Обычный HTTP (request-response):
═══════════════════════════════
Клиент: "Дай мне новые данные?" → Сервер
Сервер: ← "Вот данные" (или "ничего нового")
Клиент: (ждёт N секунд)
Клиент: "Дай мне новые данные?" → Сервер
...повторяется бесконечно
Real-time:
══════════
Клиент: "Подпишись на обновления" → Сервер
Сервер: ← "Новое сообщение!" (сразу, когда появилось)
Сервер: ← "Ещё одно сообщение!" (сразу)
Сервер: ← "Новый пользователь подключился!" (сразу)
ПриложениеReal-time функция
Мессенджеры (Telegram, WhatsApp)Мгновенные сообщения
Google DocsСовместное редактирование
Uber/Яндекс.ТаксиТрекинг водителя
Binance, TradingViewБиржевые котировки
Онлайн-игрыСостояние игры
Трелло, NotionКоллаборация в реальном времени
Системы мониторингаМетрики в реальном времени

Клиент постоянно спрашивает: “Есть что-нибудь новенькое?”

// Простой polling — каждые 5 секунд
setInterval(async () => {
const response = await fetch('/api/messages?since=' + lastId);
const data = await response.json();
if (data.messages.length > 0) {
renderMessages(data.messages);
lastId = data.messages[data.messages.length - 1].id;
}
}, 5000);

Минусы: нагрузка на сервер, задержка до 5 секунд, расход трафика.

Сервер держит запрос открытым до появления новых данных:

// Клиент
async function longPoll() {
try {
const response = await fetch('/api/messages/wait?since=' + lastId);
const data = await response.json();
renderMessages(data.messages);
lastId = data.lastId;
} finally {
longPoll(); // Сразу запускаем следующий запрос
}
}
longPoll();
// Сервер (Express)
app.get('/api/messages/wait', (req, res) => {
const since = req.query.since;
// Ждём новых сообщений (до 30 секунд)
const timeout = setTimeout(() => {
res.json({ messages: [], lastId: since });
}, 30000);
// Когда появится новое сообщение — отвечаем
emitter.once('new-message', (message) => {
clearTimeout(timeout);
res.json({ messages: [message], lastId: message.id });
});
});

Лучше polling, но всё равно создаёт накладные расходы.

Одностороннее соединение: сервер → клиент.

// Клиент — встроенный EventSource API браузера
const events = new EventSource('/api/stream');
events.onmessage = (e) => {
const data = JSON.parse(e.data);
renderUpdate(data);
};
events.addEventListener('message', (e) => {
console.log('Новое сообщение:', JSON.parse(e.data));
});

Хорош для: уведомлений, новостных лент, обновлений статуса.

Двустороннее постоянное соединение:

// Клиент
const ws = new WebSocket('wss://example.com/ws');
ws.onopen = () => ws.send(JSON.stringify({ type: 'hello' }));
ws.onmessage = (e) => console.log('Получено:', JSON.parse(e.data));
ws.onerror = (e) => console.error('Ошибка:', e);
ws.onclose = () => console.log('Соединение закрыто');

Хорош для: чатов, игр, всего двустороннего.

Peer-to-peer без сервера-посредника:

Клиент A ←——————————→ Клиент B
(прямое соединение)
Сервер нужен только для установки связи (signaling)

Хорош для: видеозвонков, peer-to-peer файлообмена.

Polling Long Poll SSE WebSocket WebRTC
─────────────────────────────────────────────────────────────────
Поддержка браузера ✅ ✅ ✅ ✅ ✅
Прост в реализации ✅ ✅ ✅ ✅ ❌
Двусторонний ❌ ❌ ❌ ✅ ✅
Автопереподключение manual manual ✅ manual ❌
Работает с прокси ✅ ✅ ✅ ✅⚠️ ❌
Без сервера ❌ ❌ ❌ ❌ ✅
Задержка высокая средняя низкая низкая низкая
Нужен поток от сервера к клиенту?
→ SSE (уведомления, ленты, статус)
Нужна двусторонняя связь?
→ WebSocket / Socket.io (чат, игры, коллаборация)
Нужно P2P без сервера?
→ WebRTC (видеозвонки, файлообмен)
Простой случай, не критична задержка?
→ Polling или Long Polling
  1. Придумай 3 сценария, где подойдёт SSE, а WebSocket избыточен
  2. Придумай 3 сценария, где нужен именно WebSocket
  3. Какую технологию использует Telegram Web? А Google Meet? Подумай, почему.

Real-time — это когда сервер сам пушит данные клиенту, не ожидая запроса. Главные технологии: SSE (просто, одностороннее) и WebSocket (мощно, двустороннее). В следующем уроке разберём WebSocket протокол изнутри.