WebSockets: двустороннее соединение с сервером
Как WebSockets ломают шаблоны HTTP 🎭
HTTP — это как односторонняя рация: ты отправил запрос, получил ответ, и всё. WebSockets — это полноценный телефонный звонок: соединение установлено, и можно говорить в обе стороны сколько угодно!
🌟 Фишка: WebSocket создаёт постоянное соединение между клиентом и сервером. Больше никаких бесконечных запросов — данные приходят мгновенно.
Под капотом: рукопожатие 🤝
WebSocket начинается с HTTP-рукопожатия. Клиент шлёт запрос с заголовком Upgrade: websocket, сервер отвечает "OK", и… вуаля! TCP-канал переключается в режим WebSocket.
// Пример запроса на соединение
const socket = new WebSocket('wss://ваш-сервер.com/chat');
socket.onopen = () => {
console.log('Соединение открыто! 🎉');
socket.send('Привет, сервер!');
};
Жизненный цикл соединения ♻️
- Открытие (
onopen) — соединение установлено - Получение данных (
onmessage) — сервер что-то прислал - Ошибка (
onerror) — что-то пошло не так - Закрытие (
onclose) — соединение разорвано
socket.onmessage = (event) => {
console.log('Получено:', event.data);
};
socket.onclose = () => {
console.log('Соединение закрыто 😢');
};
Реальный пример: чат на WebSockets 💬
Давайте создадим простой чат. Серверная часть (на Node.js с ws):
const WebSocket = require('ws');
const wss = new WebSocket.Server({ port: 8080 });
wss.on('connection', (ws) => {
ws.on('message', (message) => {
// Рассылаем сообщение всем подключённым
wss.clients.forEach(client => {
if (client.readyState === WebSocket.OPEN) {
client.send(message.toString());
}
});
});
});
Клиентская часть:
const socket = new WebSocket('ws://localhost:8080');
const input = document.getElementById('message-input');
input.addEventListener('keypress', (e) => {
if (e.key === 'Enter' && socket.readyState === WebSocket.OPEN) {
socket.send(input.value);
input.value = '';
}
});
socket.onmessage = (event) => {
const messages = document.getElementById('messages');
messages.innerHTML += `<div>${event.data}</div>`;
};
Когда WebSockets — лучший выбор? 🏆
| Сценарий | Почему WebSockets? |
|---|---|
| Онлайн-чаты | Мгновенная доставка сообщений |
| Онлайн-игры | Постоянный обмен данными |
| Биржевые тикеры | Пуш-уведомления о изменениях |
| Совместные редакторы | Реальная синхронизация |
Ошибки новичков (и как их избежать) 💥
🔹 Не проверяют readyState
Всегда проверяйте состояние соединения перед отправкой:
if (socket.readyState === WebSocket.OPEN) {
socket.send('Важные данные');
}
🔹 Забывают обрабатывать ошибки
Добавьте обработчик onerror, иначе пользователь даже не узнает о проблеме.
🔹 Не закрывают соединение
При размонтировании компонента (например, в React):
useEffect(() => {
const socket = new WebSocket(url);
return () => socket.close(); // Важно!
}, []);
Производительность: держим соединение в тонусе 🏋️♂️
- Используйте бинарные данные вместо JSON для больших объёмов
- Реализуйте heartbeat (пульс) для проверки соединения
- Сжимайте данные (например, через
permessage-deflate)
// Пример heartbeat
setInterval(() => {
if (socket.readyState === WebSocket.OPEN) {
socket.send('ping');
}
}, 30000);
Альтернативы: когда WebSockets — не панацея
Для редких уведомлений лучше Server-Sent Events (SSE). Для сложных сценариев — WebRTC (пиринговая связь). Но для большинства real-time задач WebSockets — золотая середина!
🚀 Pro-совет: В современных браузерах есть WebSocket API уровня
EventTarget, что открывает крутые возможности для обработки событий.
Что дальше?
Попробуйте реализовать:
- Простой чат (как в примере выше)
- Онлайн-рисовалку с передачей координат
- Реал-тайм дашборд с биржевыми данными
Как говорит Данила Бежин: "Лучший способ понять WebSockets — написать что-то, что невозможно без них!"