Что такое Server-Sent Events?
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Server-Sent Events (SSE)
Server-Sent Events (SSE) — это технология, которая позволяет серверу отправлять обновления на клиент в режиме реального времени через одно соединение HTTP. Это более простая альтернатива WebSocket для одностороннего потока данных от сервера к клиенту.
Основные характеристики
SSE — это стандартизованный способ передачи потока событий от сервера к браузеру:
const eventSource = new EventSource('/api/v1/stream');
eventSource.onmessage = (event) => {
console.log('Получено сообщение:', event.data);
};
eventSource.close();
Как работает?
На клиенте (JavaScript):
const eventSource = new EventSource('/api/events');
eventSource.onmessage = (event) => {
const data = JSON.parse(event.data);
console.log('Новое сообщение:', data);
};
eventSource.addEventListener('notification', (event) => {
console.log('Уведомление:', event.data);
});
eventSource.onerror = (error) => {
console.error('Ошибка SSE:', error);
};
eventSource.close();
На сервере (Node.js/Express пример):
app.get('/api/events', (req, res) => {
res.setHeader('Content-Type', 'text/event-stream');
res.setHeader('Cache-Control', 'no-cache');
res.setHeader('Connection', 'keep-alive');
res.setHeader('Access-Control-Allow-Origin', '*');
res.write('data: Первое сообщение\n\n');
res.write('event: notification\n');
res.write('data: {\"text\": \"Важное уведомление\"}\n\n');
res.write('id: 123\n');
res.write('data: Сообщение с ID\n\n');
const interval = setInterval(() => {
res.write('data: ' + new Date().toLocaleTimeString() + '\n\n');
}, 1000);
req.on('close', () => {
clearInterval(interval);
res.end();
});
});
Формат сообщений SSE
Простое сообщение:
data: Hello, World!
С полями:
event: myEvent
data: {\"message\": \"Hello\"}
id: 1
retry: 5000
Поля:
data:— содержимое сообщенияevent:— имя событияid:— уникальный IDretry:— время переподключения в миллисекундах
Практические примеры
1. Уведомления о прогрессе:
const eventSource = new EventSource('/api/v1/download/progress?fileId=123');
eventSource.addEventListener('progress', (event) => {
const progress = JSON.parse(event.data);
updateProgressBar(progress.percent);
if (progress.percent === 100) {
eventSource.close();
}
});
2. Live уведомления:
const notifications = new EventSource('/api/v1/notifications/stream');
notifications.addEventListener('new_comment', (event) => {
const comment = JSON.parse(event.data);
addCommentToDOM(comment);
showNotification('Новый комментарий');
});
3. Live цены с переподключением:
function connectToPriceStream() {
const priceStream = new EventSource('/api/v1/prices/stream');
priceStream.onmessage = (event) => {
const prices = JSON.parse(event.data);
updatePriceDisplay(prices);
};
priceStream.onerror = () => {
if (priceStream.readyState === EventSource.CLOSED) {
console.log('Соединение закрыто. Переподключение...');
setTimeout(() => connectToPriceStream(), 5000);
}
};
}
connectToPriceStream();
SSE vs WebSocket vs Polling
| Аспект | SSE | WebSocket | Polling |
|---|---|---|---|
| Направление | Server -> Client | Bidirectional | Both |
| Overhead | Низкий | Низкий | Высокий |
| Простота | Очень простая | Сложнее | Простая |
| Переподключение | Автоматическое | Manual | Каждый раз |
| Масштабируемость | Хорошая | Отличная | Низкая |
| Для двусторонней | Нет | Да | Да |
Когда использовать:
- SSE: Live feed, уведомления, потоковые данные
- WebSocket: Chat, совместное редактирование, игры
- Polling: Legacy браузеры, простые обновления
Преимущества и недостатки
Преимущества:
- Простая API в браузере (конструктор EventSource)
- Автоматическое переподключение
- Использует обычное HTTP соединение
- Лучше работает через прокси и фаервол
- Меньше overhead чем WebSocket
Недостатки:
- Только одностороннее общение
- Не поддерживается в старых браузерах (IE)
- Сложнее с масштабируемостью
- Максимум 6 соединений на домен
Обработка ошибок и переподключение
const eventSource = new EventSource('/api/stream');
let reconnectCount = 0;
const MAX_RECONNECT_ATTEMPTS = 5;
eventSource.onerror = (error) => {
console.error('SSE Error:', error);
if (reconnectCount >= MAX_RECONNECT_ATTEMPTS) {
eventSource.close();
return;
}
if (eventSource.readyState === EventSource.CLOSED) {
reconnectCount++;
setTimeout(() => {
connectToStream();
}, Math.pow(2, reconnectCount) * 1000);
}
};
Резюме
Server-Sent Events — стандартный способ отправлять потоковые обновления от сервера к браузеру. SSE проще WebSocket для одностороннего потока данных и идеально подходит для уведомлений, live feed и потоковых данных. Браузер автоматически управляет переподключением и восстановлением сообщений.