[JavaScript, Node.JS] Разработка сервера для многопользовательской игры с помощью nodejs и magx 
    
    
        
    
    
    
    
            
    
        
            
                
                                    
                
                                    
                
                    
                
            
        
    
    
        
            
                
                
                    
                           
                    
                        Автор 
                        Сообщение 
                    
                                        
                        
                            
                                
                                
                                                                                                            news_bot ®
                                                                        
                                                                                                                                                
                                                                            
                                                                                                                
                                            Стаж: 7 лет 8 месяцев                                        
                                                                                                                
                                            Сообщений: 27286                                        
                                                                                                                                                
                                                             
                            
                                
                             
                         
                        
                            
                                
                                    
                                        
                                        
 Многие разработчики начинают разработку многопользовательского онлайн сервера на основе библиотеки socket.io. Эта библиотека позволяет очень просто реализовать обмен данными между клиетом и сервером в реальном времени, но продумать и реализовать всю логику и интерфейс взаимодействия сервера с клиентами, а также архитектуру масштабирования и оптимизацию трафика все равно придется.
Я хочу рассказать про библиотеку magx, используя которую можно не задумываться о сетевой составляющей (коммуникации сервера и клиентов), a сразу сконцентрироваться на разработке логики игры и клиентского UI.
При разработке архитектуры многопользовательсой игры обычно рассматриваются 2 подхода: с авторитарным сервером и не-авторитарным (авторитарным клиентом). Оба эти подхода поддерживаются библиотекой magx. Начнем с более простого подхода — не-авторитарного.
Не-авторитарный сервер
Суть его в том, что сервер не контролирует результаты ввода каждого игрока. Клиенты самостоятельно отслеживают введенные игроком действия и игровую логику локально, после чего высылают результат определенного действия на сервер. После этого сервер синхронизирует все совершенные действия с игровым состоянием других клиентов.
Это легче реализовать с точки зрения архитектуры, так как сервер отвечает только лишь за коммуникацию между клиентами, не делая никаких дополнительных вычислений, которые делают клиенты.
С помощью библиотеки magx такой сервер можно реализовать всего в несколько строк кода:
import * as http from "http"
import { Server, RelayRoom } from "magx"
const server = http.createServer()
const magx = new Server(server)
magx.define("relay", RelayRoom)
// start server
const port = process.env.PORT || 3001
server.listen(port, () => {
  console.info(`Server started on http://localhost:${port}`)
})
Теперь, чтобы подключить клиентов к этому серверу и начать их взаимодействие, достаточно установить js библиотеку:
npm install --save magx-client
и подключить ее к проекту:
import { Client } from "magx-client"
Также можно воспользовать прямой ссылкой для использования в HTML:
<script src="https://cdn.jsdelivr.net/npm/magx-client@0.7.1/dist/magx.js"></script>
После подключиеня, всего несколько строк позволят настроить соединение и взаимодействие с сервером:
// authenticate to server
await client.authenticate()
// create or join room
const rooms = await client.getRooms("relay")
room = rooms.length
  ? await client.joinRoom(rooms[0].id)
  : await client.createRoom("relay")
console.log("you joined room", name)
// handle state patches
room.onPatch((patch) => updateState(patch))
// handle state snapshot
room.onSnapshot((snapshot) => setState(snapshot))
// handle joined players
room.onMessage("player_join", (id) => console.log("player join", id))
// handle left players
room.onMessage("player_leave", (id) => console.log("player leave", id))
Детальный пример как построить взаимодействие между клиентами и не-авторитарным сервером описано в соответствующем примере в проекте magx-examples.
Авторитарный сервер
В авторитарном сервере обработка и выполнение всех действий, затрагивающих игровой процесс, применение правил игры и обработки ввода от игроков-клиентов осуществляется на стороне сервера.
Клиент не может самостоятельно вносить какие-либо изменения в состояние игры. Вместо этого, он отправляет серверу, что конкретно он хочет сделать, сервер обрабатывает этот запрос, вносит изменения в состояние игры и отправляет обновленное состояние клиентам.
При таком подходе логика на клиенте сводится к минимуму, клиент начинает отвечать только за отрисовку состояния игры и обработку действий игрока. Преимущество такого подхода в том, что он значительно усложняет клиентам возможность использования нечестных приёмов (cheating).
Разработка авторитарного сервера требует описания состояния игры и правил взаимодействия игрока с этим состоянием на стороне сервера. В архитектуре сервере magx предполагается, что вся логика реализуется комнате (worker). Каждая комната фактически является отдельным сервером, к которому подключаются клиенты.
Данные/состояние каждой комнаты изолировано и синхронизируется только с клиентам комнаты. Одним из важнейших элементов авторитарного сервера — это система управления состоянием. Mosx — рекомендованная система управления состоянием, но архитектуре magx нет зависимости на какую-либо систему, поэтому выбор всегда остается за вами.
Описание игрового состояния
Так как вся логика игры должна строиться на основе состояния, то первым делом необходимо его описать. С помощью mosx это сделать достаточно просто — необходимо создать классы для каждого типа объектов состояния и обернуть его декоратором @mx.Object, а перед каждым свойством, по которому необходимо отслеживать изменение состояния для синхронизации с клиентами необходимо поставить декоратор @mx. Давайте рассмотрим пример состояния с коллекцией игроков:
@mx.Object
export class Player {
  @mx public x = Math.floor(Math.random() * 400)
  @mx public y = Math.floor(Math.random() * 400)
}
@mx.Object
export class State {
  @mx public players = new Map<string, Player>()
  public createPlayer(id: string) {
    this.players.set(id, new Player())
  }
  public removePlayer(id: string) {
    this.players.delete(id)
  }
  public movePlayer(id: string, movement: any) {
    const player = this.players.get(id)
    if (!player) { return }
    player.x += movement.x ? movement.x * 10 : 0
    player.y += movement.y ? movement.y * 10 : 0
  }
}
Единственное ограничение, которое необходимо учесть при проектировании состояния — необходимость использования Map() вместо вложенных объектов. Массивы (Array) и все примитивные типы (number, string, boolean) могут быть использованы без ограничений.
Описание игровой комнаты
После описания состояния и логики его изменения необходимо описать логику взаимодействия с клиентами. Для этого необходимо создать класс комнаты и описать необходимые обработчики событий:
export class MosxStateRoom extends Room<State> {
  public createState(): any {
    // create state
    return new State()
  }
  public createPatchTracker(state: State) {
    // create state change tracker
    return Mosx.createTracker(state)
  }
  public onCreate(params: any) {
    console.log("MosxStateRoom created!", params)
  }
  public onMessage(client: Client, type: string, data: any) {
    if (type === "move") {
      console.log(`MosxStateRoom received message from ${client.id}`, data)
      this.state.movePlayer(client.id, data)
    }
  }
  public onJoin(client: Client, params: any) {
    console.log(`Player ${client.id} joined MosxStateRoom`, params)
    client.send("hello", "world")
    this.state.createPlayer(client.id)
  }
  public onLeave(client: Client) {
    this.state.removePlayer(client.id)
  }
  public onClose() {
    console.log("MosxStateRoom closed!")
  }
}
Регистрация комнаты на сервере
Последний шаг — зарегистрировать комнату и сервер готов.
const magx = new Server(server, params)
magx.define("mosx-state", MosxStateRoom)
Полный исходный код рассмотренного примера доступен в репозитарии magx-examples.
Почему стоит обратить внимание на этот проект?
В заключение хотел бы упомянуть о преимуществах используемых библиотек:
Mosx
- Простой и удобный способ описания состояния через декораторы @mx
 
- Возможность применять декоратор @mx к вычисляемым свойствам.
 
- Возможность создавать приватные объекты @mx.Object.private и приватные свойства @mx.private, с различным уровнем доступа для разных игроков.
 
- Динамически изменять доступ игроков к приватным объектам.
 
- Встроенный механизм объединения объектов в группы для удобного управления правами доступа к приватным данным
 
- Возможность делать копию состояния для каждого игрока
 
- Полная поддержка Typescript
 
- Минимум зависимостей (на библиотеки MobX и patchpack — для сжатия пакетов)
Magx
- Простой и понятный API.
 
- Широкие возможности по кастомизации компонент сервера:
 
- Механизм коммуникации клиента с сервером (по умолчанию используется webockets)
 
- База данных для хранения данных комнат и сессий пользователей (по умолчанию используется локальное хранилище)
 
- Механизм коммуникации серверов при масштабировании (из коробки реализован механизм коммуникации в кластере)
 
- Способ авторизации и верификации пользователей (по умолчанию используются локальный сессии)
 
- Возможность работать в кластере из коробки
 
- Встроенные комнаты: лобби и relay (для не авторитарного сервера)
 
- JS Библиотека Magx-client для работы с сервером
 
- Мониторинговая консоль magx-monitor для управления комнатами сервера, их клиентами и просмотр состояния
 
- Полная поддержка Typescript
 
- Минимум зависимостей (на библиотеку notepack.io — для уменьшения сетевого трафика)
Данный проект достаточно молодой и надеюсь внимание комьюнити поможет ему развиваться на много быстрее.
===========
 Источник:
habr.com
===========
Похожие новости:
- [PHP, Zend Framework] Простой Telegram бот, который задаёт 1 вопрос
 
- [JavaScript, Программирование, Node.JS] Декораторы в JavaScript с нуля (перевод)
 
- [JavaScript, Программирование, ReactJS] Начинающим React-разработчикам: приложение со списком дел (покупок) (перевод)
 
- [JavaScript, Node.JS] Отправка ответа с Коа (перевод)
 
- [Разработка веб-сайтов, JavaScript, Программирование] Сниппет, расширение для VSCode и CLI. Часть 1
 
- [Разработка веб-сайтов, JavaScript, Accessibility] Безжалостное избавление от Layout Shift на netlify.com (перевод)
 
- [Разработка веб-сайтов, JavaScript] JavaScript исполняется 25 лет: краткая история языка и скидка 50% на WebStorm
 
- [Разработка веб-сайтов, JavaScript] Web Components и IoC
 
- [JavaScript, Node.JS, Яндекс API, Голосовые интерфейсы] Салют от Сбера в Яндекс.Облаке
 
- [Высокая производительность, JavaScript, Программирование, TypeScript] Производительность TypeScript (перевод)
Теги для поиска: #_javascript, #_node.js, #_magx, #_mosx, #_nodejs, #_multiplayer, #_framework, #_websockets, #_networking, #_javascript, #_node.js 
                         
                        
                            
                                                                    
                                                             
                         
                    
                    
                
                
            
        
    
    
    
    
    
            
    
            
    
        
    
    
        
                        Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
    
    
        
        Текущее время: 31-Окт 15:25
Часовой пояс: UTC + 5 
            
    
                
| Автор | Сообщение | 
|---|---|
| news_bot ® 
                                                                            
                                                                                                                
                                            Стаж: 7 лет 8 месяцев                                         | |
| Многие разработчики начинают разработку многопользовательского онлайн сервера на основе библиотеки socket.io. Эта библиотека позволяет очень просто реализовать обмен данными между клиетом и сервером в реальном времени, но продумать и реализовать всю логику и интерфейс взаимодействия сервера с клиентами, а также архитектуру масштабирования и оптимизацию трафика все равно придется. Я хочу рассказать про библиотеку magx, используя которую можно не задумываться о сетевой составляющей (коммуникации сервера и клиентов), a сразу сконцентрироваться на разработке логики игры и клиентского UI. При разработке архитектуры многопользовательсой игры обычно рассматриваются 2 подхода: с авторитарным сервером и не-авторитарным (авторитарным клиентом). Оба эти подхода поддерживаются библиотекой magx. Начнем с более простого подхода — не-авторитарного. Не-авторитарный сервер Суть его в том, что сервер не контролирует результаты ввода каждого игрока. Клиенты самостоятельно отслеживают введенные игроком действия и игровую логику локально, после чего высылают результат определенного действия на сервер. После этого сервер синхронизирует все совершенные действия с игровым состоянием других клиентов. Это легче реализовать с точки зрения архитектуры, так как сервер отвечает только лишь за коммуникацию между клиентами, не делая никаких дополнительных вычислений, которые делают клиенты. С помощью библиотеки magx такой сервер можно реализовать всего в несколько строк кода: import * as http from "http" import { Server, RelayRoom } from "magx" const server = http.createServer() const magx = new Server(server) magx.define("relay", RelayRoom) // start server const port = process.env.PORT || 3001 server.listen(port, () => { console.info(`Server started on http://localhost:${port}`) }) Теперь, чтобы подключить клиентов к этому серверу и начать их взаимодействие, достаточно установить js библиотеку: npm install --save magx-client и подключить ее к проекту: import { Client } from "magx-client" Также можно воспользовать прямой ссылкой для использования в HTML: <script src="https://cdn.jsdelivr.net/npm/magx-client@0.7.1/dist/magx.js"></script> После подключиеня, всего несколько строк позволят настроить соединение и взаимодействие с сервером: // authenticate to server await client.authenticate() // create or join room const rooms = await client.getRooms("relay") room = rooms.length ? await client.joinRoom(rooms[0].id) : await client.createRoom("relay") console.log("you joined room", name) // handle state patches room.onPatch((patch) => updateState(patch)) // handle state snapshot room.onSnapshot((snapshot) => setState(snapshot)) // handle joined players room.onMessage("player_join", (id) => console.log("player join", id)) // handle left players room.onMessage("player_leave", (id) => console.log("player leave", id)) Детальный пример как построить взаимодействие между клиентами и не-авторитарным сервером описано в соответствующем примере в проекте magx-examples. Авторитарный сервер В авторитарном сервере обработка и выполнение всех действий, затрагивающих игровой процесс, применение правил игры и обработки ввода от игроков-клиентов осуществляется на стороне сервера. Клиент не может самостоятельно вносить какие-либо изменения в состояние игры. Вместо этого, он отправляет серверу, что конкретно он хочет сделать, сервер обрабатывает этот запрос, вносит изменения в состояние игры и отправляет обновленное состояние клиентам. При таком подходе логика на клиенте сводится к минимуму, клиент начинает отвечать только за отрисовку состояния игры и обработку действий игрока. Преимущество такого подхода в том, что он значительно усложняет клиентам возможность использования нечестных приёмов (cheating). Разработка авторитарного сервера требует описания состояния игры и правил взаимодействия игрока с этим состоянием на стороне сервера. В архитектуре сервере magx предполагается, что вся логика реализуется комнате (worker). Каждая комната фактически является отдельным сервером, к которому подключаются клиенты. Данные/состояние каждой комнаты изолировано и синхронизируется только с клиентам комнаты. Одним из важнейших элементов авторитарного сервера — это система управления состоянием. Mosx — рекомендованная система управления состоянием, но архитектуре magx нет зависимости на какую-либо систему, поэтому выбор всегда остается за вами. Описание игрового состояния Так как вся логика игры должна строиться на основе состояния, то первым делом необходимо его описать. С помощью mosx это сделать достаточно просто — необходимо создать классы для каждого типа объектов состояния и обернуть его декоратором @mx.Object, а перед каждым свойством, по которому необходимо отслеживать изменение состояния для синхронизации с клиентами необходимо поставить декоратор @mx. Давайте рассмотрим пример состояния с коллекцией игроков: @mx.Object export class Player { @mx public x = Math.floor(Math.random() * 400) @mx public y = Math.floor(Math.random() * 400) } @mx.Object export class State { @mx public players = new Map<string, Player>() public createPlayer(id: string) { this.players.set(id, new Player()) } public removePlayer(id: string) { this.players.delete(id) } public movePlayer(id: string, movement: any) { const player = this.players.get(id) if (!player) { return } player.x += movement.x ? movement.x * 10 : 0 player.y += movement.y ? movement.y * 10 : 0 } } Единственное ограничение, которое необходимо учесть при проектировании состояния — необходимость использования Map() вместо вложенных объектов. Массивы (Array) и все примитивные типы (number, string, boolean) могут быть использованы без ограничений. Описание игровой комнаты После описания состояния и логики его изменения необходимо описать логику взаимодействия с клиентами. Для этого необходимо создать класс комнаты и описать необходимые обработчики событий: export class MosxStateRoom extends Room<State> { public createState(): any { // create state return new State() } public createPatchTracker(state: State) { // create state change tracker return Mosx.createTracker(state) } public onCreate(params: any) { console.log("MosxStateRoom created!", params) } public onMessage(client: Client, type: string, data: any) { if (type === "move") { console.log(`MosxStateRoom received message from ${client.id}`, data) this.state.movePlayer(client.id, data) } } public onJoin(client: Client, params: any) { console.log(`Player ${client.id} joined MosxStateRoom`, params) client.send("hello", "world") this.state.createPlayer(client.id) } public onLeave(client: Client) { this.state.removePlayer(client.id) } public onClose() { console.log("MosxStateRoom closed!") } } Регистрация комнаты на сервере Последний шаг — зарегистрировать комнату и сервер готов. const magx = new Server(server, params) magx.define("mosx-state", MosxStateRoom) Полный исходный код рассмотренного примера доступен в репозитарии magx-examples. Почему стоит обратить внимание на этот проект? В заключение хотел бы упомянуть о преимуществах используемых библиотек: Mosx 
 Magx 
 Данный проект достаточно молодой и надеюсь внимание комьюнити поможет ему развиваться на много быстрее. =========== Источник: habr.com =========== Похожие новости: 
 | |
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
    Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 31-Окт 15:25
Часовой пояс: UTC + 5 
