Как стать автором
Обновить

Как создать веб-сервер для игры с мультиплеером бесплатно

Уровень сложностиПростой

Проблема

Предположим, что вы хотите создать браузерную игру используя нативный JS или игровой движок, который поддерживает Web-экспорт (Godot, Unity).

Если ваша игра имеет небольшой трафик, например такой как Дурак или Монополия, где действия игроков пошаговые, вы можете ограничиться использованием Long-Pooling'ом посылая запрос раз в несколько секунд. Но что делать, когда вам нужно знать информацию о других игроках чуть ли не каждую четверть секунды, а то и чаще?

Решение

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

Для игры с мультиплеером я решил сделать Пасьянс-Паук в котором, можно было бы помогать друг-другу.

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

Сам бэкенд будет на NodeJS, для запуска PeerJS сервера достаточно будет создать peer.js файл:

const express = require('express');
const app = express();
const ExpressPeerServer = require('peer').ExpressPeerServer;
const server = app.listen(3001);
const cors = require('cors');

app.use(cors());

peerServer = ExpressPeerServer(server);
app.use('/peerjs', peerServer); // на этот роут идет подключение по PeerJS

peerServer.on('connection', function(client) {
    console.log('client connected: ' + client.getId());
});

peerServer.on('disconnect', function (client) {
    console.log('client disconnected: ' + client.getId());
});

app.get('/ping', function(req, res) {
    res.send('pong!');
});

// Вечный цикл, чтобы держать сервер активным
setInterval(() => {
    fetch(`${your_render_server_name}.onrender.com/ping`, {
        method: 'GET',
    });
}, 480000);

И package.json:

{
  "scripts": {
    "peer": "node peer.js"
  },
  "dependencies": {
    "cors": "^2.8.5",
    "express": "^4.21.2",
    "ioredis": "^5.4.2",
    "peer": "^1.0.2"
  }
}

Мы будем использовать ExpressPeerServer, вместо PeerServer чтобы позже можно было добавить роутеры на поиск/создание/удаление игр.

Теперь сам клиент, который будет использовать наша игра. Для подключения игрока к другому игроку нужно сначала подключиться к Peer серверу

peerJs = new Peer(peerId, { // peerId - Строка с уникальным ID
    host: host, // сервер куда подключаться без указания протокола пример: server.onrender.com
    path: '/peerjs', // роут peerjs, должен совпадать с сервером
    secure: true,
});

И обработать события на подключение к нам

peerJs.on('open', function () {
    console.log('connected to peer server');
});

peerJs.on('error', function (err) {
    console.log(err);
});

peerJs.on('connection', function (conn) {
    _initConn(conn); // обработка соединения другого игрока
});

peerJs.on('disconnected', function() {
    peerJs.reconnect();
});

Чтобы подключится к другому игроку, который уже подключился к Peer серверу, нужно написать

const conn = peerJs.connect(`${other_player_peer_id}`);
_initConn(conn); // обработка соединения другого игрока

function _initConn(conn) {
  conn.on('open', function () {
      playerConnections[conn.peer] = conn;
  });

  conn.on('data', function (data) {
      // обработать данные
  });

  conn.on('close', function () {
      delete playerConnections[conn.peer];
  });
}

Примечание: Если в нашей игре больше чем 2 игрока, при подключении игрока к хосту, ему нужно отправить peer_id других игроков, чтобы он подключился и к ним. Если вы собираетесь делать игру, где хост и является сервером, то требуется позаботиться о передаче данных между игроками.

Заключение

Теперь вы можете создать свой сервер для игры с мультиплеером, используя данный метод, но из минусов, так как сервер не обрабатывает данные пользователей вы не сможете проверять, что игрок не читер и не отправляет другим игрокам "плохие" данные. Я решаю данную проблему валидацией в самой игре.

Мою игру вы можете найти на Яндекс Игры или на itch.io.

Теги:
Хабы:
Данная статья не подлежит комментированию, поскольку её автор ещё не является полноправным участником сообщества. Вы сможете связаться с автором только после того, как он получит приглашение от кого-либо из участников сообщества. До этого момента его username будет скрыт псевдонимом.