Кто был инициатором отправки данных на WebSocket в проекте?

«Кто был инициатором отправки данных на WebSocket в проекте?» — вопрос из категории Софт-скиллы, который задают на 26% собеседований Node.js Разработчик. Ниже — развёрнутый пример ответа, который можно адаптировать под свой опыт.

Ответ

В моем последнем Node.js проекте с реальным временем обновления данных, инициация WebSocket соединений была распределенной:

Клиентская инициация:

  • Первичное подключение всегда инициировалось клиентом при загрузке SPA
  • Подписка на конкретные каналы данных (например, /stocks/AAPL)
// Клиентский код (браузер)
const socket = new WebSocket('wss://api.example.com/ws');
socket.onopen = () => {
  socket.send(JSON.stringify({
    type: 'subscribe',
    channel: 'user-notifications',
    userId: currentUser.id
  }));
};

Серверная инициация:

  • Push-уведомления о системных событиях (новые сообщения, обновления статусов)
  • Рассылка обновлений при изменении данных в Redis pub/sub
  • Heartbeat-сообщения для поддержания соединения
// Серверный код (Node.js + ws)
const WebSocket = require('ws');
const wss = new WebSocket.Server({ port: 8080 });
const redis = require('redis');
const redisClient = redis.createClient();

// Подписка на Redis канал
redisClient.subscribe('system-alerts');
redisClient.on('message', (channel, message) => {
  // Рассылка всем подключенным клиентам
  wss.clients.forEach((client) => {
    if (client.readyState === WebSocket.OPEN) {
      client.send(JSON.stringify({
        type: 'alert',
        channel: channel,
        data: JSON.parse(message)
      }));
    }
  });
});

// Сервер инициирует отправку по таймеру
setInterval(() => {
  wss.clients.forEach((client) => {
    if (client.readyState === WebSocket.OPEN) {
      client.send(JSON.stringify({ type: 'ping', timestamp: Date.now() }));
    }
  });
}, 30000);

Архитектурное решение: Мы использовали гибридный подход. Клиенты подписывались на интересующие их каналы, а сервер инициировал отправку при наступлении событий. Это позволило снизить нагрузку и дать клиентам контроль над получаемыми данными.