← Назад к вопросам

В WebSocket приходит только информация или и методы

2.0 Middle🔥 131 комментариев
#Браузер и сетевые технологии

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI2 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

В WebSocket приходит только информация или и методы

Ответ: Через WebSocket приходит только информация (данные), не методы. Давайте разберём почему и как правильно структурировать взаимодействие.

Основной принцип

WebSocket - это канал передачи данных, не кода. Через него можно отправлять:

  • JSON объекты
  • Строки
  • Бинарные данные
  • Но НЕ функции или методы
// В WebSocket приходит ТАК:
{
  "type": "user:login",
  "payload": {
    "id": 123,
    "name": "John"
  }
}

// А НЕ ТАК:
{
  "type": "user:login",
  "method": function() { ... }, // НЕЛЬЗЯ!
  "action": () => { ... }        // НЕЛЬЗЯ!
}

Почему нельзя отправлять методы

1. JSON не поддерживает функции

const obj = {
  name: "John",
  greet: function() { return "Hi"; }
};

const json = JSON.stringify(obj);
console.log(json);
// Результат: {"name":"John"}
// Метод greet потеряется!

2. Функции специфичны для JavaScript Функция написана на JavaScript, но сервер может быть на Python, Go, Java. Он не может выполнить JavaScript функцию.

3. Security - это очень опасно Если сервер отправит функцию, клиент её выполнит. Это позволит серверу выполнять произвольный код на клиенте.

// Опасно - eval выполняет произвольный код
const code = 'steal_password()';
eval(code); // ВЗЛОМ!

Правильная архитектура WebSocket

Сервер отправляет данные:

// server.js
socket.emit('user:login', {
  id: 123,
  name: 'John',
  role: 'admin'
});

Клиент получает данные и вызывает методы:

// client.js
socket.on('user:login', (userData) => {
  // userData - это объект с данными
  console.log(userData.name); // 'John'
  
  // ТЫ РЕШАЕШЬ, что делать с этими данными
  updateUserUI(userData);     // твой метод
  saveToCache(userData);      // твой метод
  notifyAboutLogin(userData); // твой метод
});

Паттерн сообщений через WebSocket

Типичная структура:

// Сообщение от сервера
{
  "event": "notification:new",
  "data": {
    "id": "notif-123",
    "message": "You have a new message",
    "timestamp": "2024-01-01T10:00:00Z"
  }
}

Клиент обрабатывает это сообщение:

const handlers = {
  'notification:new': (data) => {
    showNotification(data.message);
    playSound();
    updateBadgeCount();
  },
  'user:online': (data) => {
    updateUserStatus(data.userId, 'online');
  },
  'message:received': (data) => {
    addMessageToChat(data.message);
    scrollToBottom();
  }
};

socket.on('message', (message) => {
  const handler = handlers[message.event];
  if (handler) {
    handler(message.data); // вызови нужный метод
  }
});

Пример: Chat через WebSocket

Сервер отправляет сообщение:

// server.py
socket.emit('chat:message', {
  id: 'msg-123',
  author: 'John',
  text: 'Hello everyone!',
  timestamp: datetime.now(),
  hasAttachments: False
})

Клиент получает и обрабатывает:

// client.js
const messageHandlers = {
  async processMessage(data) {
    // 1. Добавь в UI
    this.addMessageToDOM(data);
    
    // 2. Проверь на содержимое
    if (this.containsAlert(data.text)) {
      this.highlightMessage(data.id);
    }
    
    // 3. Сохрани в локальное хранилище
    await this.saveToCache(data);
    
    // 4. Отправь анализ на сервер (если нужно)
    if (data.hasAttachments) {
      this.processAttachments(data);
    }
  }
};

socket.on('chat:message', (message) => {
  messageHandlers.processMessage(message);
});

Правильный паттерн: Command Pattern

Если нужно, чтобы сервер "приказал" клиенту что-то сделать, используй команды как данные:

// Сервер отправляет КОМАНДУ как данные
socket.emit('command', {
  type: 'redirect',
  payload: {
    url: '/dashboard',
    replace: true
  }
});

// Клиент получает команду и исполняет нужный метод
const commands = {
  redirect: (payload) => {
    window.location.href = payload.url;
  },
  reload: () => {
    window.location.reload();
  },
  logout: () => {
    clearAuth();
    window.location.href = '/login';
  },
  playSound: (payload) => {
    const audio = new Audio(payload.url);
    audio.play();
  }
};

socket.on('command', (message) => {
  const command = commands[message.type];
  if (command) {
    command(message.payload);
  }
});

Пример: Real-time Notifications

Сервер:

# Когда пользователю нужно что-то сделать
socket.emit('notification', {
    'action_type': 'show_toast',
    'message': 'New order received',
    'duration': 3000,
    'variant': 'success'
})

Клиент:

const notificationActions = {
  show_toast: (data) => {
    showToast(data.message, {
      duration: data.duration,
      variant: data.variant
    });
  },
  
  open_dialog: (data) => {
    openDialog(data.title, data.content);
  },
  
  update_state: (data) => {
    setAppState(data.newState);
  }
};

socket.on('notification', (message) => {
  const action = notificationActions[message.action_type];
  if (action) {
    action(message);
  }
});

JSON строго: только данные

// ДА - только данные
JSON.stringify({
  type: 'update',
  value: 42,
  timestamp: Date.now()
});
// {"type":"update","value":42,"timestamp":1234567890}

// НЕТ - функции теряются
JSON.stringify({
  type: 'update',
  value: 42,
  timestamp: new Date(),
  callback: () => console.log('done') // пропадёт
});
// {"type":"update","value":42,"timestamp":"2024-01-01T10:00:00.000Z"}

Обработка команд безопасно

Всегда валидируй входящие данные:

const validateCommand = (command) => {
  const validTypes = ['redirect', 'reload', 'logout', 'playSound'];
  
  if (!validTypes.includes(command.type)) {
    console.error('Unknown command:', command.type);
    return false;
  }
  
  // Дополнительные проверки
  if (command.type === 'redirect') {
    if (!isValidURL(command.payload.url)) {
      console.error('Invalid URL');
      return false;
    }
  }
  
  return true;
};

socket.on('command', (message) => {
  if (!validateCommand(message)) return;
  
  const command = commands[message.type];
  command(message.payload);
});

TypeScript типизация

// Типы сообщений
type ServerMessage = 
  | { type: 'user:login'; data: User }
  | { type: 'chat:message'; data: Message }
  | { type: 'command'; data: Command };

type Command = 
  | { type: 'redirect'; payload: { url: string } }
  | { type: 'logout'; payload: null }
  | { type: 'playSound'; payload: { url: string } };

// Обработка
const handleMessage = (message: ServerMessage) => {
  switch (message.type) {
    case 'user:login':
      updateUser(message.data);
      break;
    case 'chat:message':
      addMessage(message.data);
      break;
    case 'command':
      executeCommand(message.data);
      break;
  }
};

Итог

Через WebSocket приходит ТОЛЬКО информация (данные):

  • JSON объекты
  • Строки
  • Числа
  • Arrays
  • Но НЕ функции

Правило архитектуры:

  1. Сервер отправляет ДАННЫЕ и КОМАНДЫ (как данные)
  2. Клиент получает данные
  3. Клиент решает, какой из своих МЕТОДОВ вызвать
  4. Методы находятся только на клиенте

Это безопаснее, надёжнее и позволяет серверу быть на любом языке программирования.

В WebSocket приходит только информация или и методы | PrepBro