> For the complete documentation index, see [llms.txt](https://docs.edgegap.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.edgegap.com/ru/learn/brauzer-serverov.md).

# Браузер серверов

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

Быстро начните работу с Server Browser и изучите примеры сценариев для различных жанров.

Server Browser — это управляемый сервис для [Развертывания](/ru/learn/orkestraciya/deployments.md#match-bound) и [Постоянных](/ru/learn/orkestraciya/postoyanstvo.md) серверов:

* **помогать игрокам искать и присоединяться к подходящим серверам** на основе вместимости, задержки или игровых параметров;
* **заранее прогревать новые серверы** чтобы обслуживать глобальную аудиторию в масштабе и предотвращать раздражающие очереди;
* **упрощать работу серверов** включая обновления, перезапуски, персистентность, mesh-сети и многое другое.

{% hint style="success" %}
Нужно подбирать игроков по строгим правилам, не позволяя им выбирать сервер? Рассмотрите [Матчмейкинг](/ru/learn/matchmeiking.md).
{% endhint %}

## ✔️ Подготовка

**Тестирование этого сервиса полностью бесплатно, кредитная карта не требуется.**

Бесплатный тариф предоставляет до 3 часов работы на нашем общем тестовом кластере после каждой перезагрузки.

В этом руководстве предполагается, что вы уже:

* [поняли модель развёртывания Edgegap](https://docs.edgegap.com/ru/learn/pages/4ad5d792bc82dceeaec6d7dd56165ae188da0417#id-1.-just-in-time-deployment-dedicated-servers),
* опубликовали ваше серверное приложение на Edgegap ([Unreal Engine](/ru/unreal-engine.md), [Unity](/ru/unity.md)),
* успешно подключились с игрового клиента к вашему серверу на Edgegap.

### Функции и поток

<figure><img src="https://3845012722-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FsR0dHSFv9ymoC0DO5G8J%2Fuploads%2Fnwlt2Ot2ahlyLvI7kdGx%2Fimage.png?alt=media&amp;token=14b5a6c8-48c8-4f23-a50a-0783acab14e3" alt=""><figcaption><p>Server Browser: поток и иерархия</p></figcaption></figure>

Server Browser предлагает две основные функции:

[#start-browsing](#start-browsing "mention") с интеграцией клиента и сервера:

* Клиенты резервируют места с помощью одного метода и получают данные для подключения.
* Клиенты могут просматривать подходящие серверы и слоты с использованием пользовательских фильтров (внутриигровой интерфейс).
* Серверы подтверждают подключения игроков на серверах с помощью [Федеративной идентификации](#user-content-fn-1)[^1].
* Серверы обновляют вместимость слота и метаданные, чтобы изменить видимость или запустить масштабирование.

[#automated-scaling](#automated-scaling "mention") (необязательная функция) с политиками масштабирования:

* Отслеживайте доступные экземпляры серверов, слоты, вместимость — по региону или по собственным критериям.
* Развертывайте новые серверы для увеличения вместимости с предварительным прогревом или масштабированием just-in-time.
* Автоматизируйте операции с изолированными политиками для событий с ограниченным временем (QA-тест, турнир).

{% hint style="info" %}
После выхода игры **ваш браузер серверов должен работать 24/7** чтобы игроки по всему миру могли присоединяться к серверам.
{% endhint %}

## ▶️ Начать просмотр

Изучите жизненный цикл сервера и игрока (клиента), чтобы обеспечить эффективное использование серверов.

**Быстро начните — добавьте наш SDK в вашу игру**:

* Unreal Engine [Инструменты разработчика](/ru/unreal-engine/developer-tools.md#integration-kit):
  * [прочитайте документацию](https://egik.betide.studio/) от Betide Studios,
  * [установите из Fab Marketplace](https://www.fab.com/listings/ff17ad88-12a1-49cf-9a41-31695ed11e16) (бесплатно для личного использования).
* Unity [Инструменты разработчика](/ru/unity/developer-tools.md#software-development-kit):
  * [установите пакет бесплатно с помощью Unity Package Manager](https://github.com/edgegap/edgegap-unity-sdk),
  * [изучите наше руководство для начала работы и полные примеры](/ru/unity/matchmaking.md).

### Аутентификация

Все запросы должны отправлять `Authorization`  HTTP-заголовок с вашим секретом **Токен аутентификации:**

<pre><code>Авторизация: <a data-footnote-ref href="#user-content-fn-2">xxxxxxxx-e458-4592-b607-c2c28afd8b62</a>
</code></pre>

{% hint style="warning" %}
**Храните ваши токены в секрете и в безопасности! Сотрудники Edgegap никогда не будут просить у вас ваши токены.**
{% endhint %}

{% hint style="info" %}
Токен Matchmaker и токены Server Browser являются отдельными от токенов Edgegap API.
{% endhint %}

Server Browser автоматически генерирует два типа токенов:

* **Токен сервера** — требуется для [методов Server API,](#server-lifecycle) может быть [внедрен как переменная версии приложения](/ru/learn/orkestraciya/application-and-versions.md#injected-variables).
  * даёт доступ ко всем методам API, удобно для тестирования, DevOps или собственного масштабирования.
* **Токен клиента** — требуется для [Monitor API и Seat Reservation API](#player-lifecycle) используется игровыми клиентами.

{% hint style="success" %}
Храните токен клиента в секретном хранилище бэкенда игры, чтобы упростить ротацию токена в production.
{% endhint %}

### Обнаружение экземпляра

Обнаружение — это процесс, при котором полностью инициализированный сервер уведомляет Server Browser и становится видимым [через поиск или автоматически назначенные резервации](#allocate-capacity).

{% hint style="warning" %}
**Новый** [Развертывания](/ru/learn/orkestraciya/deployments.md) **должен создать новый экземпляр** при инициализации, чтобы отслеживать добавленную вместимость.
{% endhint %}

{% hint style="info" %}
См. [#automated-scaling](#automated-scaling "mention") чтобы узнать о политиках масштабирования и автоматически запускать развертывания.
{% endhint %}

**Необходимая информация** для каждого экземпляра сервера включает:

* при инициализации экземпляра должен быть определён как минимум один слот,
* данные для подключения к серверу — URL, IP, информация о порте и местоположение.

**Необязательные пользовательские параметры метаданных** для фильтрации игроков, сортировки и просмотра; например:

* информация о слоте — вместимость команды и метаданные, специфичные для команды (например, название команды),
* имя и теги — настраиваемые, уникальные, человекочитаемые и доступные для поиска метки;
* данные о совместимости — версия сервера или поддерживаемые версии клиента;
* критерии задержки — идентификаторы города и региона, а также назначенные [Пинг-маяки](/ru/learn/orkestraciya/ping-beacons.md) сведения;
* игровые параметры — уровень/сцена/карта, игровой режим, сложность, используемые моды;
* любые другие пользовательские параметры, которые помогут игрокам отфильтровать и найти подходящий сервер.

{% hint style="info" %}
Параметры метаданных выше — лишь примеры, вы можете определить любое количество параметров по необходимости.
{% endhint %}

{% hint style="success" %}
Чтобы сериализовать вложенные объекты, закодируйте путь доступа к ним в ключе как `"object.child.property"`.
{% endhint %}

Серверы могут **обновлять метаданные экземпляра или слота в любое время** чтобы изменить критерии их обнаруживаемости. При обновлении метаданных все индексируемые ключи должны быть указаны с допустимыми значениями (даже если они не изменялись).

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

{% hint style="info" %}
См. [Постоянство](/ru/learn/orkestraciya/postoyanstvo.md) для управления постоянным состоянием мира и [Приложения и версии](/ru/learn/orkestraciya/application-and-versions.md#active-caching) для более быстрых развертываний.
{% endhint %}

### Выделение вместимости

Вместимость экземпляра и слота может выделяться двумя способами, по отдельности или вместе:

* [#auto-assigned-reservation](#auto-assigned-reservation "mention") чтобы выбрать сервер, запущенный с определённой политикой масштабирования,
* [#search-and-browse](#search-and-browse "mention") позволяет игроку задать фильтры и просматривать подходящие серверы, чтобы выбрать вручную.

{% hint style="success" %}
Мы рекомендуем начать с [#auto-assigned-reservation](#auto-assigned-reservation "mention") как с более простого варианта.
{% endhint %}

#### Автоматически назначаемая резервация

{% hint style="info" %}
Реализуйте автоматическое назначение, чтобы **автоматически выбирать сервер**на основе региона игрока.
{% endhint %}

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

Если для этой резервации нет подходящего слота экземпляра, ответ:

* **код статуса указывает состояние масштабирования политики** и если добавляется больше вместимости,
* при масштабировании вверх, **заголовок `Retry-After`  указывает время ожидания (в секундах) перед повторной попыткой**.

После завершения резервации вы можете перейти к [#connect-to-server](#connect-to-server "mention").

#### Поиск и просмотр

{% hint style="info" %}
Реализуйте пользовательский поиск для **собственных критериев фильтрации и/или чтобы показывать игрокам список серверов.**
{% endhint %}

Игроки могут перечислять экземпляры серверов с пользовательскими фильтрами и сортировкой, а также [постранично просматривать результаты](#pagination) чтобы найти сервер, к которому они хотят присоединиться. Слоты каждого экземпляра можно искать тем же способом.

Экземпляры и слоты можно фильтровать и сортировать с помощью встроенных параметров или [индексируемых метаданных](#configuration):

<table><thead><tr><th width="400">Свойство</th><th width="140">Тип данных</th><th width="105">Экземпляр</th><th width="105">Слот</th></tr></thead><tbody><tr><td><code>request_id</code></td><td><code>string</code></td><td>✅</td><td>❌</td></tr><tr><td><code>total_joinable_seats</code>, <code>total_available_seats</code></td><td><code>int</code></td><td>✅</td><td>❌</td></tr><tr><td><code>name</code></td><td><code>string</code></td><td>❌</td><td>✅</td></tr><tr><td><code>available_seats</code>, <code>reserved_seats</code></td><td><code>int</code></td><td>❌</td><td>✅</td></tr><tr><td><code>created_at</code>, <code>updated_at</code></td><td><code>string</code></td><td>✅</td><td>✅</td></tr><tr><td><code>metadata.{index}</code> (пользовательский)</td><td><code>string</code>, <code>int</code>, <code>float</code>, <code>bool</code></td><td>✅</td><td>✅</td></tr></tbody></table>

Доступные операторы фильтрации зависят от типа данных фильтруемого свойства:

<table><thead><tr><th width="125">Параметр</th><th width="135">Операторы</th><th>Пример фильтра (на основе простого примера)</th></tr></thead><tbody><tr><td><code>string</code></td><td><p><a data-footnote-ref href="#user-content-fn-3"><code>eq</code></a>  или <a data-footnote-ref href="#user-content-fn-4"><code>ne</code></a> или </p><p><a data-footnote-ref href="#user-content-fn-5"><code>lt</code></a>  или <a data-footnote-ref href="#user-content-fn-6"><code>le</code></a> или </p><p><a data-footnote-ref href="#user-content-fn-7"><code>gt</code></a>  или <a data-footnote-ref href="#user-content-fn-8"><code>ge</code></a>  или<br><code>содержит</code>  или<br></p></td><td><pre><code>?$filter=metadata.custom_name contains 'my game'
and metadata.server_version le '1.1.0'
and metadata.server_version ge '1.0.0'
&#x26;$order=metadata.custom_name asc
</code></pre></td></tr><tr><td><code>string</code></td><td>литеральные значения<br><code>in</code>  (фильтр)<br><code>rank</code>  (сортировка)</td><td><pre><code>?$filter=metadata.city in ('Chicago', 'Toronto')
&#x26;$order=rank(metadata.city, 'Chicago', 'Toronto')
</code></pre></td></tr><tr><td><code>int</code>, <code>float</code></td><td><p><a data-footnote-ref href="#user-content-fn-3"><code>eq</code></a>  или <a data-footnote-ref href="#user-content-fn-4"><code>ne</code></a> или </p><p><a data-footnote-ref href="#user-content-fn-5"><code>lt</code></a>  или <a data-footnote-ref href="#user-content-fn-6"><code>le</code></a> или </p><p><a data-footnote-ref href="#user-content-fn-7"><code>gt</code></a>  или <a data-footnote-ref href="#user-content-fn-8"><code>ge</code></a>  </p></td><td><pre><code>?$filter=metadata.xp_multiplier gt 1.0
&#x26;$order=metadata.xp_multiplier desc
</code></pre></td></tr><tr><td><code>bool</code></td><td><a data-footnote-ref href="#user-content-fn-3"><code>eq</code></a>  или <a data-footnote-ref href="#user-content-fn-4"><code>ne</code></a></td><td><pre><code>?$filter=metadata.allows_new_connections eq true
</code></pre></td></tr></tbody></table>

{% hint style="success" %}
Фильтрация и сортировка по пользовательскому `metadata.city`  для наилучшей задержки после измерения с помощью [Пинг-маяки](/ru/learn/orkestraciya/ping-beacons.md).
{% endhint %}

{% hint style="info" %}
Узнайте о курсорной [#pagination](#pagination "mention") чтобы позволить пользователям загружать больше результатов.
{% endhint %}

#### Резервирование мест

**Перед присоединением к серверу игроки должны зарезервировать места** чтобы убедиться, что экземпляр предлагает достаточную доступную вместимость, и предотвратить переполнение. Резервации могут включать группу игроков или одного игрока.

Федеративная идентификация: игроки должны указать уникальный идентификатор игрока стороннего сервиса в своей резервации. Как только они [#connect-to-server](#connect-to-server "mention")отправляют тот же идентификатор для проверки на стороне сервера.

После успешного создания резервации игрокам следует немедленно попытаться подключиться. Ожидающие **резервации истекают через 30 с (настраивается), если не подтверждены** сервером.

**Резервации, превышающие вместимость мест для присоединения в слоте, отклоняются** ([409 Conflict](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Status/409)). Места, доступные для присоединения, — это любые доступные места, которые ещё не были зарезервированы другими игроками.

### Подключиться к серверу

Сразу после резервирования места **игроки должны перейти к подключению к игровому серверу вашего развертывания и передать свой идентификатор игрока через RPC netcode**.

{% tabs %}
{% tab title="Unreal Engine" %}
Чтобы **подключиться из PIE (Editor)** во время разработки и тестирования нажмите клавишу тильды `~`  и введите `open {URL}:{port}` и дождитесь загрузки карты в вашем редакторе.

{% hint style="success" %}
Если подключение не удалось или экран чёрный, обратитесь к нашему [руководству по устранению неполадок](/ru/unreal-engine.md#troubleshooting-and-faq-1).
{% endhint %}
{% endtab %}

{% tab title="Unity" %}
Чтобы **подключить ваш Unity Editor** или **игровой клиент** к вашему облачному развертыванию, введите:

* **Развертывание** **URL** указывающий на IP сервера, обычно в `NetworkManager`  компоненте.
* **Внешний порт** сопоставленный с [внутренним портом прослушивания сервера](https://docs.edgegap.com/learn/advanced-features/application-and-versions#port-mapping)обычно в компоненте Transport.

{% hint style="success" %}
В случае тайм-аута подключения или других проблем обратитесь к нашему [руководству по устранению неполадок](/ru/unity.md#troubleshooting-and-faq-4).
{% endhint %}
{% endtab %}
{% endtabs %}

Чтобы аутентифицировать новые подключения, **ваш сервер должен отправить массовый запрос на подтверждение резервации** со всеми идентификаторами новых игроков, получив в ответ:

* назначение принятых резерваций игроков в их предпочтительный слот,
* назначение истёкших резерваций игроков в их предпочтительный слот,
* список неизвестных идентификаторов игроков.

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

{% hint style="info" %}
Ваш сервер обладает полномочиями изменять вместимость любого слота, добавлять, удалять или обновлять любые слоты — удаляя все резервации для этого слота, если ожидающие резервации превышают доступные места.
{% endhint %}

### Покинуть сервер

Когда игроки уходят, ваш **сервер должен увеличивать количество доступных мест для назначенного слота**.

{% hint style="success" %}
Если ваш сервер допускает период повторного подключения, он может подождать перед обновлением слотов.
{% endhint %}

Читайте о [Постоянство](/ru/learn/orkestraciya/postoyanstvo.md#recovery-objectives) чтобы предотвратить раздражающие откаты постоянного сервера.

## 🚀 Автоматическое масштабирование

Server Browser совместим с несколькими различными методами авто-масштабирования:

* **метод предварительного прогрева** — запуск серверов строго с политиками масштабирования Server Browser,
* **метод just-in-time** — запуск через [Матчмейкинг](/ru/learn/matchmeiking.md) и [заполнение через Server Browser](#allocate-capacity),
* **собственный autoscaler** — запуск через собственный игровой бэкенд и [заполнение через Server Browser](#allocate-capacity).

Следующее руководство будет посвящено **предварительному прогреву с политиками масштабирования**.

<figure><img src="https://3845012722-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FsR0dHSFv9ymoC0DO5G8J%2Fuploads%2F0RCiModlkLY6BVAjcrFJ%2Fimage.png?alt=media&amp;token=7f7c5639-13ad-4780-9839-b9e4bd67fe80" alt=""><figcaption><p>UI политик масштабирования Server Browser</p></figcaption></figure>

{% hint style="success" %}
Останавливайте развертывания в [Unreal Engine](/ru/unreal-engine.md#stop-deployments), [Unity](/ru/unity.md#stop-deployments)или [с помощью API](/ru/docs/api/vydelennye-servery.md#delete-v1-self-stop-request_id-access_point_id) чтобы надёжно контролировать стоимость серверов.
{% endhint %}

### Мониторинг вместимости

Server Browser будет обновлять список обнаруженных экземпляров каждые [`monitoring_interval`](#user-content-fn-9)[^9] .

{% hint style="warning" %}
Чтобы **предотвратить переразвертывание**задайте интервал мониторинга немного выше среднего времени запуска сервера.
{% endhint %}

{% hint style="info" %}
Каждая политика должна использовать фильтр (с использованием [синтаксиса фильтрации](#search-and-browse)) для мониторинга региональной вместимости.
{% endhint %}

Ваш настроенный [`minimum_active_instances`](#user-content-fn-10)[^10]  значение может рассматриваться либо как:

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

#### Фиксированная вместимость

Политики фиксированной вместимости не должны использовать фильтры, связанные с местами.

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

В качестве альтернативы игры с [Постоянство](/ru/learn/orkestraciya/postoyanstvo.md) обычно хотят поддерживать долго работающие серверы, особенно когда игрокам предлагается предоставлять [Постоянство](/ru/learn/orkestraciya/postoyanstvo.md#community-servers).

{% hint style="info" %}
Политика масштабирования помогает автоматически перезапускать и перерабатывать упавшие серверы на лету.
{% endhint %}

#### Предварительно прогретый резерв

Политики предварительного прогрева должны использовать фильтры по местам, доступным для присоединения, для контроля использования вместимости.

Запускайте ожидающие бездействующие серверы, чтобы опережать спрос игроков, если:

* вы запускаетесь глобально и ожидаете быстрый приток игроков за короткий промежуток времени,
* или инициализация сервера требует более 30 секунд ([не включая время развертывания](#user-content-fn-11)[^11]),
* или серверы используют стратегии mesh, требующие более сложной сетевой топологии.

### Развертывать серверы

Новые развертывания запускаются автоматически, когда количество обнаруженных экземпляров*s* падает ниже минимума активных экземпляров, заданного политикой. После [`deployment_registration_period`](#user-content-fn-9)[^9]  истекшего времени, развертывания повторяются бесконечно через каждый интервал мониторинга.

{% hint style="warning" %}
**Обязательно проверьте вашу** [**авто-обнаружение серверов**](#discover-instance) **интеграцию с фильтром вашей политики, иначе ваша политика может зациклиться бесконечно и создать большое количество неиспользуемых развертываний!**
{% endhint %}

{% hint style="info" %}
Развертывания могут использовать [Частные флоты](/ru/learn/orkestraciya/chastnye-floty.md) (с переносом в облако) или напрямую Cloud.
{% endhint %}

Доступные параметры включают ([см. полную спецификацию API](/ru/docs/api/vydelennye-servery.md#private-fleets)):

* [**приложение и версия**](/ru/learn/orkestraciya/application-and-versions.md) — версия сборки, ресурсы и другие параметры оркестрации,
* **пользователи** — один набор географических координат для предпочтительного [размещения сервера](/ru/learn/orkestraciya/deployments.md#regional-standby),
* [**идентификаторы частных хостов**](/ru/learn/orkestraciya/chastnye-floty.md) — оставьте пустым для облака или укажите хосты в желаемом регионе,
* [**теги**](/ru/learn/orkestraciya/deployments.md#dashboard-monitoring) — помечайте названием политики, чтобы позже находить развертывания, запущенные с этой политикой,
* [**переменные окружения**](/ru/learn/orkestraciya/deployments.md#custom-variables) — передавайте пользовательские параметры и секреты серверам,
* [**webhooks**](/ru/learn/orkestraciya/deployments.md#webhooks-and-postbacks) — уведомляйте ваш игровой бэкенд (или матчмейкер) о событиях жизненного цикла развертывания,
* [**требовать кэшированные местоположения**](/ru/learn/orkestraciya/application-and-versions.md#active-caching) — если вы предпочитаете более быстрые развертывания только в кэшированных местоположениях.

### Примеры политик

Тестируйте и изменяйте любые из этих политик по необходимости. В большинстве игр будет использоваться несколько политик.

{% tabs %}
{% tab title="🍀 QA-экземпляр" %}
Простая политика, чтобы постоянно держать один сервер развернутым для тестирования.

<pre class="language-json" data-title=""><code class="lang-json">{
  "name": "sb-qa-pool",
<strong>  <a data-footnote-ref href="#user-content-fn-12">"filter"</a>: "metadata.policy_name eq 'sb-qa-pool'",
</strong>  "deployment_request": {
    "private_host_ids": [],
    "application": <a data-footnote-ref href="#user-content-fn-13">"my-game-server"</a>,
    "version": <a data-footnote-ref href="#user-content-fn-14">"2024.01.30-16.23.00-UTC"</a>,
    "users": [
      {
        "user_type": "geo_coordinates",
        "<a data-footnote-ref href="#user-content-fn-15">данные пользователя</a>": {
<strong>          "latitude": 41.881832,
</strong><strong>          "longitude": -87.623177
</strong>        }
      }
    ],
<strong>    "tags": ["sb-qa-pool"],
</strong>    "environment_variables": [
      {
<strong>        "key": "SB_SCALING_POLICY_NAME",
</strong><strong>        "value": "sb-qa-pool",
</strong>        "is_hidden": false
      }
    ]
  },
<strong>  "minimum_active_instances": 1
</strong>}
</code></pre>

{% endtab %}

{% tab title="🌡️ Регион предварительного прогрева" %}
Запускайте развёртывания в 10 раз чаще в ожидании спроса. Копируйте для каждого региона.

<pre class="language-json" data-title=""><code class="lang-json">{
  "name": "sb-v1.0.0-chicago",
<strong>  <a data-footnote-ref href="#user-content-fn-16">"filter"</a>": "total_joinable_seats gt 0 and metadata.policy_name eq 'sb-v1.0.0-chicago'",
</strong>  "deployment_request": {
    "private_host_ids": [],
    "application": <a data-footnote-ref href="#user-content-fn-13">"my-game-server"</a>,
    "version": <a data-footnote-ref href="#user-content-fn-14">"2024.01.30-16.23.00-UTC"</a>,
    "users": [
      {
        "user_type": "geo_coordinates",
        "<a data-footnote-ref href="#user-content-fn-15">данные пользователя</a>": {
<strong>          "latitude": 41.881832,
</strong><strong>          "longitude": -87.623177
</strong>        }
      }
    ],
<strong>    "tags": ["sb-v1.0.0-chicago"],
</strong>    "environment_variables": [
      {
<strong>        "key": "SB_SCALING_POLICY_NAME",
</strong><strong>        "value": "sb-v1.0.0-chicago",
</strong>        "is_hidden": false
      }
    ]
  },
<strong>  <a data-footnote-ref href="#user-content-fn-17">"minimum_active_instances"</a>: 10
</strong>}
</code></pre>

{% endtab %}

{% tab title="🔑 Сообщество" %}
Добавляйте развёртывания при падении доступной ёмкости ниже порога. Копируйте для каждого региона.

<pre class="language-json" data-title=""><code class="lang-json">{
<strong>  "name": "sb-mmo-chicago",
</strong><strong>  <a data-footnote-ref href="#user-content-fn-18">"filter"</a>": "total_joinable_seats gt 5 and metadata.policy_name eq 'sb-mmo-chicago'",
</strong>  "deployment_request": {
<strong>    <a data-footnote-ref href="#user-content-fn-19">"private_host_ids"</a>": ["alpha-north-america-95fab093"],
</strong>    "application": <a data-footnote-ref href="#user-content-fn-13">"my-game-server"</a>,
    "version": <a data-footnote-ref href="#user-content-fn-14">"2024.01.30-16.23.00-UTC"</a>,
    "users": [
      {
        "user_type": "geo_coordinates",
        "<a data-footnote-ref href="#user-content-fn-15">данные пользователя</a>": {
<strong>          "latitude": 41.881832,
</strong><strong>          "longitude": -87.623177
</strong>        }
      }
    ],
<strong>    "tags": ["sb-mmo-chicago"],
</strong>    "environment_variables": [
      {
<strong>        "key": "SB_SCALING_POLICY_NAME",
</strong><strong>        "value": "sb-mmo-chicago",
</strong>        "is_hidden": false
      }
    ],
<strong>    <a data-footnote-ref href="#user-content-fn-20">"webhook_on_terminated"</a>: {
</strong>      "url": "https://my-webhook.com"
    }
  },
<strong>  "minimum_active_instances": 3
</strong>}
</code></pre>

{% endtab %}

{% tab title="🔑 Сообщество" %}
По одной политике на владельца сервера, с передачей собственного пароля, заданного владельцем.

<pre class="language-json" data-title=""><code class="lang-json">{
<strong>  "name": "sb-owner-jnjnc8mid",
</strong><strong>  <a data-footnote-ref href="#user-content-fn-21">"filter"</a>": "metadata.policy_name eq 'sb-owner-jnjnc8mid'",
</strong>  "deployment_request": {
<strong>    <a data-footnote-ref href="#user-content-fn-19">"private_host_ids"</a>": ["alpha-north-america-95fab093"],
</strong>    "application": <a data-footnote-ref href="#user-content-fn-13">"my-game-server"</a>,
    "version": <a data-footnote-ref href="#user-content-fn-14">"2024.01.30-16.23.00-UTC"</a>,
    "users": [
      {
        "user_type": "geo_coordinates",
        "<a data-footnote-ref href="#user-content-fn-15">данные пользователя</a>": {
<strong>          "latitude": 41.881832,
</strong><strong>          "longitude": -87.623177
</strong>        }
      }
    ],
<strong>    "tags": ["community", "sb-owner-jnjnc8mid"],
</strong>    "environment_variables": [
      {
<strong>        "key": "SB_SCALING_POLICY_NAME",
</strong><strong>        "value": "sb-owner-jnjnc8mid",
</strong>        "is_hidden": false
      },
      {
<strong>        "key": "SB_SERVER_PASSWORD",
</strong><strong>        "value": "password1234",
</strong>        "is_hidden": false
      }
    ],
<strong>    <a data-footnote-ref href="#user-content-fn-22">"webhook_on_ready"</a>: {
</strong>      "url": "https://my-webhook.com"
    },
<strong>    <a data-footnote-ref href="#user-content-fn-23">"webhook_on_error"</a>: {
</strong>      "url": "https://my-webhook.com"
    },
<strong>    <a data-footnote-ref href="#user-content-fn-20">"webhook_on_terminated"</a>: {
</strong>      "url": "https://my-webhook.com"
    }
  },
  "minimum_active_instances": 1
}
</code></pre>

{% endtab %}
{% endtabs %}

## ⚙️ Конфигурация

API Server Browser генерируется на основе вашей JSON-конфигурации при запуске Server Browser. Вы можете задавать собственные временные окна истечения/регистрации и собственные метаданные:

{% tabs %}
{% tab title="🍀 Простой пример" %}

<pre class="language-json" data-title="sb-simple-example-v1-1-0.json"><code class="lang-json">{
	"version": "1.1.0",
	"server_instances": {
		"expiration_period": "1m",
		"<a data-footnote-ref href="#user-content-fn-24">индексы</a>": {
			"policy_name": "string",
			"name": "string"
		}
	},
	"server_instance_slots": {
		"<a data-footnote-ref href="#user-content-fn-24">индексы</a>": {}
	},
	"seat_reservations": {
		"expiration_period": "30s"
	},
	"scaling_policies": {
		"monitoring_interval": "10s",
		"deployment_registration_period": "1m"
	},
  "rate_limits": {
    "per_client_ip": 5
  }
}
</code></pre>

{% endtab %}

{% tab title="🎈 Социальные игры" %}

<pre class="language-json" data-title="sb-social-example-v1-1-0.json"><code class="lang-json">{
	"version": "1.1.0",
	"server_instances": {
		"expiration_period": "15s",
		"<a data-footnote-ref href="#user-content-fn-24">индексы</a>": {
			"policy_name": "string",
			"name": "string",
			"third_party_id": "string",
			"level": "string",
			"mode": "string",
			"difficulty": "string",
			"seed": "string",
			"max_players": "int",
			"app_version": "string",
			"location.city": "string"
		}
	},
	"server_instance_slots": {
		"<a data-footnote-ref href="#user-content-fn-24">индексы</a>": {
			"third_party_id": "string",
			"max_players": "int",
			"avg_latency": "int",
			"player_ids": "string"
		}
	},
	"seat_reservations": {
		"expiration_period": "30s"
	},
	"scaling_policies": {
		"monitoring_interval": "10s",
		"deployment_registration_period": "30s"
	},
  "rate_limits": {
    "per_client_ip": 5
  }
}
</code></pre>

{% endtab %}

{% tab title="🤝 Кооперативные игры" %}

<pre class="language-json" data-title="sb-cooperative-example-v1-1-0.json"><code class="lang-json">{
	"version": "1.1.0",
	"server_instances": {
		"expiration_period": "15s",
		"<a data-footnote-ref href="#user-content-fn-24">индексы</a>": {
			"policy_name": "string",
			"name": "string",
			"third_party_id": "string",
			"level": "string",
			"mode": "string",
			"difficulty": "string",
			"avg_rank": "int",
			"max_players": "int",
			"app_version": "string",
			"tags": "string",
			"match_id": "string",
			"location.city": "string"
		}
	},
	"server_instance_slots": {
		"<a data-footnote-ref href="#user-content-fn-24">индексы</a>": {
			"third_party_id": "string",
			"max_players": "int",
			"player_ids": "string"
		}
	},
	"seat_reservations": {
		"expiration_period": "30s"
	},
	"scaling_policies": {
		"monitoring_interval": "10s",
		"deployment_registration_period": "30s"
	},
  "rate_limits": {
    "per_client_ip": 5
  }
}
</code></pre>

{% endtab %}

{% tab title="⚔️ Соревновательные игры" %}

<pre class="language-json" data-title="sb-competitive-example-v1-1-0.json"><code class="lang-json">{
	"version": "1.1.0",
	"server_instances": {
		"expiration_period": "15s",
		"<a data-footnote-ref href="#user-content-fn-24">индексы</a>": {
			"policy_name": "string",
			"name": "string",
			"third_party_id": "string",
			"avg_rank": "int",
			"max_players": "int",
			"is_ranked": "bool",
			"app_version": "string",
			"cpu_frequency": "int",
			"match_id": "string",
			"location.city": "string"
		}
	},
	"server_instance_slots": {
		"<a data-footnote-ref href="#user-content-fn-24">индексы</a>": {
			"third_party_id": "string",
			"max_players": "int",
			"avg_rank": "int",
			"avg_latency": "int"
		}
	},
	"seat_reservations": {
		"expiration_period": "30s"
	},
	"scaling_policies": {
		"monitoring_interval": "10s",
		"deployment_registration_period": "15s"
	},
  "rate_limits": {
    "per_client_ip": 5
  }

</code></pre>

{% endtab %}
{% endtabs %}

{% hint style="info" %}
Для наилучшей производительности не включайте индексы, которые не используются для фильтрации или сортировки. Неиндексированные параметры по-прежнему можно задавать и читать с помощью методов API или SDK, специфичного для движка.
{% endhint %}

## ☁️ Хостинговый кластер

Server Browser удобно размещается и обслуживается Edgegap круглосуточно, 24/7.

Выберите вариант хостинга, лучше всего подходящий для вашей цели:

* **Бесплатный кластер (общий)** чтобы протестировать все функции и исследовать синергии с вашим дизайном,
  * автоматически отключается через 3 часа, для продолжения тестирования требуется перезапуск.
* **Приватный кластер** **(выделенный)** чтобы обеспечить стабильную среду для ваших производственных нужд,
  * выберите ваш регион и получите круглосуточную поддержку живых игр для выпуска с уверенностью.

#### Уровни частного кластера

В настоящее время мы предлагаем [3 уровня частных кластеров](https://edgegap.com/resources/pricing#managed-infrastructure) для любых потребностей:

<table><thead><tr><th width="160">Уровень</th><th align="right">Любительский уровень</th><th align="right">Студийный уровень</th><th align="right">Корпоративный уровень</th></tr></thead><tbody><tr><td>Лучше всего подходит для</td><td align="right">энтузиасты,<br>разработчики-одиночки</td><td align="right">коммерческие релизы</td><td align="right">запуски с высоким трафиком</td></tr><tr><td>Ограничение частоты запросов (запросов/с)</td><td align="right">200</td><td align="right">750</td><td align="right">2,000</td></tr><tr><td>Ресурсы</td><td align="right">1 vCPU + 2 ГБ ОЗУ</td><td align="right">6 vCPU + 12 ГБ ОЗУ</td><td align="right">18 vCPU + 48 ГБ ОЗУ</td></tr><tr><td>Резервирование</td><td align="right">1 виртуальный узел</td><td align="right">3 виртуальных узла</td><td align="right">3 виртуальных узла</td></tr><tr><td>Цена, за час</td><td align="right">$0.0312</td><td align="right"> $0.146</td><td align="right">$0.548</td></tr><tr><td><strong>Цена, за 30 дней</strong><br>(непрерывное использование)</td><td align="right"><strong>$22.464</strong></td><td align="right"><strong>$105.12</strong></td><td align="right"><strong>$394.56</strong></td></tr></tbody></table>

🌟 Обновите бесплатные инстансы до частного кластера одним кликом и получите высокодоступный хостинг, поддерживаемый командой Edgegap, с круглосуточной живой поддержкой для публично выпущенных игр.

Требования к ресурсам для вашего инстанса будут зависеть от факторов:

* **количество игроков,** больше игроков ⇒ больше API-запросов и выше загрузка CPU,
* **запросы на игрока,** более частые повторные попытки ⇒ выше использование ресурсов CPU,
* **количество серверов,** больше серверов ⇒ выше загрузка CPU и использование памяти,
* **логика резервного повторного запроса клиента** - повторные попытки без jittered backoff ⇒ [эффект лавины](https://en.wikipedia.org/wiki/Thundering_herd_problem),
* **средняя длительность матча** - более короткие сессии ⇒ более высокая частота событий жизненного цикла.

{% hint style="info" %}
Наши кластеры используют облачные машины с процессорами AMD/Intel с тактовой частотой до 3,7 ГГц.
{% endhint %}

## 📗 API

**Рассмотрите наши SDK** [**Unreal Engine**](/ru/unreal-engine/developer-tools.md) **или** [**Unity**](/ru/unity/server-browser.md) **чтобы начать с готовых примеров.**

{% hint style="info" %}
Unity/Android — рассмотрите возможность [использования подстановки в сырой строке](https://www.c-sharpcorner.com/article/convert-string-to-json-in-c-sharp/) чтобы предотвратить удаление кода жестко заданных JSON-файлов.
{% endhint %}

{% hint style="success" %}
**Веб-интерфейс Swagger**: при развертывании вашего управляемого сервиса генерируется спецификация OpenAPI и удобный веб-интерфейс, полезный для тестирования крайних случаев или проверки структуры полезных данных.
{% endhint %}

{% file src="/files/ffccd4f3b6ecf3f56a51fda820bfa44d3d52ed88" %}

Импортируйте спецификацию API в [Scalar API Web Client](https://client.scalar.com/workspace/default/request/default) или [Swagger Editor](https://editor.swagger.io/) чтобы изучить детали.

### Ограничения скорости

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

Ограничение настраивается с помощью [#configuration](#configuration "mention") параметра `rate_limits.per_client_ip`.

{% hint style="warning" %}
Если ваши игровые клиенты не повторяют запросы после получения ответа `429 Too Many Requests` **некоторые игроки могут не суметь присоединиться к серверам** во время кратковременных всплесков и периодов пиковой нагрузки.
{% endhint %}

{% hint style="success" %}
**Мы рекомендуем тестировать поведение приложения с более низкими лимитами скорости во время разработки (1 запрос/с).**
{% endhint %}

#### Нагрузочное тестирование

Нагрузочное тестирование в среде, похожей на производственную, связано со стоимостью хостинга развертывания. См. ресурсы и цены, связанные с каждым уровнем, на [нашей странице с тарифами](https://edgegap.com/resources/pricing#matchmaker).

{% hint style="warning" %}
**Используйте** [**частные кластеры**](#private-cluster-tiers) **для стресс-тестирования.** Бесплатные экземпляры строго ограничены и предназначены только для тестирования в разработке.
{% endhint %}

При проектировании нагрузочного теста, **пожалуйста, учитывайте реалистичные модели поведения игроков**:

| Реалистичный сценарий                                                                                      | Нереалистичный шаблон трафика                                                                   |
| ---------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------- |
| ✅ Игроки постепенно присоединяются к игре, увеличивая число запросов в секунду в течение нескольких часов. | ❌ Все игроки скоординированно обращаются к API в одну и ту же секунду.                          |
| ✅ Игроки ждут всё больше времени между повторными попытками (например, 1 с – 5 с – 10 с – 10 с).           | ❌ Все игроки повторяют попытку немедленно при получении `429 Слишком много запросов`  ответа.   |
| ✅ Большинство игроков получат свои назначения в течение короткого времени (10–60 с) и прекратят опрос.     | ❌ Все игроки продолжают опрашивать в течение заданного времени даже после получения назначения. |
| ✅ Большинство игроков завершают свою игру (это занимает время), прежде чем начать новую сессию.            | ❌ Все игроки немедленно перезапускают свою сессию сразу после получения назначения сервера.     |
| ✅ Пиковый трафик сохраняется примерно 6 часов в день, после чего часть часовых поясов отключается.         | ❌ Пиковый трафик сохраняется 24 часа в сутки, и все игроки играют и днём и ночью.               |

#### Поведение под нагрузкой

**Клиентские запросы** - если какой-либо клиент достигает настроенного лимита запросов/с на IP, он получает `429 Too Many Requests`  и должен сделать паузу (подождать) перед повторной попыткой.

**Запросы на развёртывание** - если политики масштабирования инициируют больше развёртываний, чем допустимый лимит запросов/с вашей организации, ваш Server Browser будет автоматически повторять попытку каждый интервал мониторинга, используя взвешенную циклическую стратегию (round-robin) между всеми политиками инстансов.

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

### Пагинация

**Server Browser предоставляет курсорную пагинацию для поэтапного получения отфильтрованных результатов в определённом порядке.** Этот подход требует отправки курсора (точки старта) и размера страницы (количества элементов ответа) при каждом получении дополнительных результатов, в отличие от традиционной пагинации limit-offset.

{% hint style="info" %}
Курсорная пагинация в сочетании с нашей системой индексирования экземпляров по метаданным обеспечивает наиболее последовательный и в то же время гибкий пользовательский опыт для фильтрации высокодинамичных данных.
{% endhint %}

Главный приоритет — чтобы пользователи находили подходящий сервер на первой странице.

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

## 🔖 Журнал изменений

Пожалуйста, см. [Примечания к релизам](/ru/docs/release-notes.md) для актуального журнала изменений этого сервиса.

#### Семантическое версионирование

Наши инструменты разработчика и управляемые сервисы используют официальную [Семантическое версионирование](https://semver.org/), указывая, какие обновления ✅ безопасны (минорные, патч), а какие могут содержать ⚠️ ломающие изменения (мажорные).

**После выпуска версии она никогда не будет модифицирована/изменена**.

{% hint style="warning" %}
**Чтобы обновить версию сервиса — остановите, измените, перезапустите.** Быстрый перезапуск не применит изменения версии.
{% endhint %}

[^1]: идентификаторов игроков сторонних сервисов

[^2]: пример значения

[^3]: равно

[^4]: не равно

[^5]: меньше чем

[^6]: меньше или равно

[^7]: больше чем

[^8]: больше или равно

[^9]: см. Конфигурацию

[^10]: см. Примеры политик

[^11]: используйте активное кэширование, чтобы легко сократить время развертывания

[^12]: * фиксированная вместимость
    * предполагает, что экземпляры передают имя политики в метаданных из внедрённой переменной

[^13]: замените на собственное имя приложения

[^14]: замените на собственную версию приложения

[^15]: Координаты Чикаго

[^16]: * развёртывается, когда найдено менее 10 присоединяемых инстансов
    * предполагает, что экземпляры передают имя политики в метаданных из внедрённой переменной

[^17]: мы ожидаем как минимум 10 развёртываний в регионе Чикаго

[^18]: * развёртывается, когда найдено менее 3 инстансов с 5 или менее присоединяемыми слотами
    * предполагает, что экземпляры передают имя политики в метаданных из внедрённой переменной

[^19]: предпочитать частный пул, если доступна ёмкость

[^20]: уведомлять игровой бэкенд при перезапуске сервера

[^21]: * не отслеживает ёмкость
    * предполагает, что экземпляры передают имя политики в метаданных из внедрённой переменной

[^22]: уведомлять игровой бэкенд, когда всё готово

[^23]: уведомлять игровой бэкенд, когда развёртывание завершается с ошибкой

[^24]: индексы содержат ваши пользовательские параметры метаданных, используемые для фильтрации или сортировки
