Введение в веб-сокеты и их использование в играх, чатах и ​​многом другом!

Обновлено 6 мая 2023 г.

Приложения реального времени и веб-сокеты

Что такое веб-сокеты?

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

Представьте себе многопользовательскую аркадную онлайн-игру с таблицей лидеров, которая постоянно меняется на сервере.

Вместо того, чтобы каждому игроку (клиенту) постоянно обновлять свой браузер, чтобы увидеть эти изменения, протокол WebSocket обеспечивает двустороннее, постоянноесоединение. это позволило бы серверу транслировать результаты всем подключенным игрокам. Это отличается от традиционных HTTP-запросов, которые требуют нового подключения для каждого запроса и ответа.

Этот пример иллюстрирует основное использование WebSockets, но его преимущества также включают в себя низкую задержку и снижение нагрузки на сервер, что в совокупности обеспечивает более плавное и беспрепятственное взаимодействие с пользователем. Это особенно важно для онлайн-игр!

Расскажите мне больше об основах WebSockets.

Ого, много требует?

С появлением приложений реального времени (например, такси, заказ еды, фондовые биржи и т. д.) протокол WebSocket решает проблему постоянного опроса сервера на наличие обновлений. Это, в свою очередь, также снижает нагрузку на ресурсы сервера, что может привести к задержке или устареванию данных для клиента. Можно себе представить, как неприятно было бы, если бы заказанный вами Uber был в одной минуте десять минут назад.

Постоянное соединение устанавливается через рукопожатие WebSocket. Клиент инициирует это рукопожатие, отправляя HTTP-запрос, на который сервер затем отвечает «ответом на обновление», указывающим на его готовность установить указанное соединение.

Протокол WebSocket использует простой формат сообщений для связи между клиентом и сервером. И клиент, и сервер могут отправлять сообщения друг другу в любое время в виде фреймов, и эти фреймы могут быть в любом формате, например в виде текста или двоичных данных. Эти данные также шифруются для предотвращения прослушивания и других угроз безопасности с использованием так называемого протокола Secure Sockets Layer (SSL).

Веб-сокеты предназначены для работы с различными транспортными протоколами, включая HTTP и HTTPS, а также поддерживаются большинством современных веб-браузеров.

Библиотеки веб-сокетов

Это круто и все такое… Так какую библиотеку мне использовать?

Прямо в точку, я вижу.

Когда дело доходит до библиотек WebSocket специально для JavaScript, следует рассмотреть несколько популярных вариантов. Socket.IO, пожалуй, самый известный, с широким набором функций и большим активным сообществом. ws — более легкий вариант, популярный благодаря своей простоте и скорости. SockJS, с другой стороны, является резервной библиотекой, которую можно использовать, когда соединения WebSocket недоступны, предоставляя более универсальное решение. Мы сосредоточимся на Socket.IO, так как он наиболее популярен.

Почему Socket.IO популярен?

Socket.IO популярен благодаря доступности API и широкому набору функций. Он имеет встроенную поддержку таких вещей, как мультиплексирование, пространства имен и управление комнатами, а также резервные варианты для сред, которые не поддерживают соединения WebSocket.

… Мультиплексирование? Пространства имен?

Мультиплексирование — это возможность устанавливать несколько соединений с использованием одного физического соединения. Клиент может создать несколько «каналов» в рамках одного соединения и отправлять и получать сообщения разных типов по отдельным каналам. Примером этого может быть чат-приложение с несколькими чатами.

Пространство имен — это способ группировать каналы на основе общей темы или цели, что упрощает управление общением. Используя наш пример приложения чата, приложение может иметь «общее» пространство имен для общедоступных чатов и «частное» пространство имен для частных комнат.

Мы не будем слишком углубляться во все функции, но документацию стоит проверить. Одним из недостатков этих функций, влияющих на производительность приложения, является увеличение накладных расходов.

Это мне не по плечу.

Хороший.

Накладные расходы просто относятся к дополнительным данным, которые необходимо передавать между клиентом и сервером для поддержания соединения в реальном времени. Больше данных означает больше сетевого трафика, что приводит к более высокому использованию ресурсов как на стороне клиента, так и на стороне сервера. Можно представить, что если пропускная способность сети будет ограничена, производительность приложения может пострадать, и нам, разработчикам, придется либо оптимизировать приложение, либо найти альтернативные решения для минимизации этих накладных расходов. Прежде чем мы рассмотрим альтернативные решения, давайте настроим наш собственный сервер для использования WebSockets!

На практике

Хорошо, можете ли вы показать мне, как использовать Socket.IO?

Это буквально то, что я сказал, должно было произойти.

Откройте терминал и выполните следующее:

npm install socket.io 

С помощью npm устанавливаем Socket.io.

В нашем редакторе кода мы собираемся настроить два файла: server.js и client.js.

// server.js

const io = require('socket.io')(3000);

io.on('connection', (socket) => {
  console.log('A user connected');
  
  socket.on('disconnect', () => {
    console.log('User disconnected');
  });
  
  // Broadcast to all clients
  socket.on('message', (data) => {
    console.log(`Received message: ${data}`);
    io.emit('message', data);
  });
});

Здесь мы объявили Socket.io как константную переменную и установили локальный порт 3000. Мы настроили сервер, вызвав метод «.on». Это должно быть знакомо разработчикам, которые настраивают серверы с помощью Express.js. Журналы консоли уведомляют нас, когда клиент подключается, отключается, а также транслируют данные всем подключенным клиентам.

// client.js
const socket = io('http://localhost:3000');

socket.on('connect', () => {
  console.log('Connected to server');
});

socket.on('disconnect', () => {
  console.log('Disconnected from server');
});

socket.on('message', (data) => {
  console.log(`Received message: ${data}`);
});

Файл клиента выглядит довольно похоже, поскольку он подключается к серверу через тот же порт, записывает сообщения на консоль при подключении и отключении и регистрирует получение сообщения от сервера.

Давайте разберем более сложный пример в виде многопользовательской игры в шахматы.

// ChessGame server-side 
const app = require('express')();
const http = require('http').createServer(app);
const io = require('socket.io')(http);

io.on('connection', (socket) => {
  console.log('a user connected');

  // Join a room
  socket.join('game');

  // Listen for a "move" event from the client
  socket.on('move', (data) => {
    // Broadcast the move to all clients in the room
    io.to('game').emit('move', data);
  });

  // Listen for a "disconnect" event from the client
  socket.on('disconnect', () => {
    console.log('user disconnected');
  });
});

http.listen(3000, () => {
  console.log('listening on *:3000');
});
// ChessGame Client-side
const socket = io();

// Emit a "move" event when the user clicks a button
document.querySelector('#move-btn').addEventListener('click', () => {
  const data = { x: 10, y: 20 };
  socket.emit('move', data);
});

// Listen for a "move" event from the server
socket.on('move', (data) => {
  // Update the game board with the new move
  updateChessBoard(data);
});

Здесь у нас есть более сложный пример игровой комнаты, к которой могут присоединяться клиенты (игроки). Когда клиент «испускает» событие «перемещение», сервер транслирует событие «перемещение» всем клиентам в игровой комнате.

Клиентская сторона прослушивает событие «перемещение» и соответствующим образом обновляет шахматную доску. Аккуратный!

Управляемые решения

Круто. Круто, круто, круто... Что, если я не хочу настраивать свой собственный сервер?

Вы всегда можете оплатить услугу! Ура капитализму!

Существует ряд платных решений, таких как Pusher, которые занимаются инфраструктурой и управлением соединениями WebSocket, освобождая разработчика от настройки собственного сервера.

Преимущества этого включают масштабируемость, балансировку нагрузки и снижение накладных расходов. Pusher гарантирует, что сервер сможет обрабатывать растущее число подключений и трафика, не требуя дополнительных ресурсов или ручной настройки. Никто не хочет играть в управление ресурсами!

Другими преимуществами, о которых стоит упомянуть, являются надежность, безопасность и специализированная поддержка. Управляемые решения следует рассматривать, когда приоритетом является экономия времени. Одно предостережение, на которое следует обратить внимание, заключается в том, что управляемые решения могут не понадобиться для небольших проектов или стартапов с ограниченным бюджетом.

В конце концов, управляемое решение избавляет вас от головной боли, связанной с настройкой и обслуживанием собственной серверной инфраструктуры, что может сэкономить время и деньги в зависимости от масштаба и масштаба проекта.

TLDR

WebSockets — это мощный инструмент, который можно использовать для создания приложений реального времени, таких как игры и чаты, которые создают постоянное соединение между клиентом и сервером. С помощью WebSockets мы можем добиться низкой задержки и снизить нагрузку на сервер, что приводит к более плавному взаимодействию с пользователем. Доступно множество библиотек с открытым исходным кодом, а также платные услуги по управлению серверной инфраструктурой. И на этом я оставлю вас с банальной шуткой, написанной нашей языковой моделью дружелюбного соседства ИИ:

Почему WebSocket разорвал HTTP-соединение?

Потому что надоело ждать ответа!

Это было ужасно.

Рекомендации