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('Привет, сервер!');
};

Жизненный цикл соединения ♻️

  1. Открытие (onopen) — соединение установлено
  2. Получение данных (onmessage) — сервер что-то прислал
  3. Ошибка (onerror) — что-то пошло не так
  4. Закрытие (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, что открывает крутые возможности для обработки событий.

Что дальше?

Попробуйте реализовать:

  1. Простой чат (как в примере выше)
  2. Онлайн-рисовалку с передачей координат
  3. Реал-тайм дашборд с биржевыми данными

Как говорит Данила Бежин: "Лучший способ понять WebSockets — написать что-то, что невозможно без них!"

Скрыть рекламу навсегда

🎥 YouTube: программирование простым языком

Канал, где я спокойно и по шагам объясняю сложные темы — без заумных терминов и лишней теории.

Подходит, если раньше «не заходило», но хочется наконец понять.

▶️ Смотреть курсы на YouTube