> 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).

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

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

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

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

{% hint style="success" %}
Хотите подбирать игроков по строгим правилам, не позволяя выбирать сервер? Рассмотрите [Подбор игроков](/ru/learn/podbor-igrokov.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.

### Функции и Flow

<figure><img src="/files/96a599df5c2103cc6318a87085a3f561be54cddc" alt=""><figcaption><p>Server Browser: Flow и иерархия</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 %}

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

Узнайте о жизненном цикле сервера/игрока и их обязанностях, чтобы обеспечить эффективное использование серверов.

{% embed url="<https://youtu.be/P8xWrD4UCxg>" %}

### Аутентифицировать

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

<pre><code>Authorization: <a data-footnote-ref href="#user-content-fn-2">xxxxxxxx-e458-4592-b607-c2c28afd8b62</a>
</code></pre>

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

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

* **Токен сервера** - требуется для [API сервера](#server-lifecycle) методов, может быть [внедрен как переменная версии приложения](/ru/learn/orkestraciya/application-and-versions.md#injected-variables).
  * Предоставляет доступ ко всем методам API и удобен для тестирования, DevOps или пользовательской оркестровки.
* **Токен клиента** - требуется для [API мониторинга и API резервирования мест](#player-lifecycle) используется игровыми клиентами.
  * Мы рекомендуем хранить этот токен во внешнем хранилище секретов, чтобы упростить ротацию токенов.

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

{% 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 keep-alive** чтобы подтвердить их текущую доступность и не допустить, чтобы игроки подключались к аварийно завершившимся или офлайн-серверам. При отсутствии heartbeat в течение заданного периода истечения экземпляр и все ожидающие резервирования мест будут автоматически удалены.

{% hint style="info" %}
См. [Персистентность](/ru/learn/orkestraciya/persistentnost.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>строка</code></td><td>✅</td><td>❌</td></tr><tr><td><code>total_joinable_seats</code>, <code>total_available_seats</code></td><td><code>целое число</code></td><td>✅</td><td>❌</td></tr><tr><td><code>name</code></td><td><code>строка</code></td><td>❌</td><td>✅</td></tr><tr><td><code>available_seats</code>, <code>reserved_seats</code></td><td><code>целое число</code></td><td>❌</td><td>✅</td></tr><tr><td><code>created_at</code>, <code>updated_at</code></td><td><code>строка</code></td><td>✅</td><td>✅</td></tr><tr><td><code>metadata.{index}</code> (пользовательский)</td><td><code>строка</code>, <code>целое число</code>, <code>число с плавающей точкой</code>, <code>логическое</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>строка</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>contains</code></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>целое число</code>, <code>число с плавающей точкой</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>логическое</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" %}
Отфильтруйте по метаданным регионов и/или городов, чтобы сузить выбор до измерения задержки до серверов.
{% endhint %}

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

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

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

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

После успешного создания резервирования ([200 OK](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Status/200)) игрокам следует немедленно попытаться подключиться. Ожидающие **резервирования истекают через 30 секунд (настраивается), если не подтверждены** вашим сервером.

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

{% hint style="info" %}
Сервер может принудительно изменять емкость любого слота, добавлять, удалять или обновлять любые слоты. **Все резервирования для данного слота будут удалены, если какие-либо ожидающие резервирования превысят новую доступную емкость слота.**
{% endhint %}

### Подключение к серверу

Как только игрок находит подходящий экземпляр, он **получает необходимые данные для подключения из** (URL или IP, [Внешний порт](/ru/learn/orkestraciya/application-and-versions.md#port-mapping)). Как только резервирование места создано, **игроки могут подключиться к игровому серверу вашего развертывания и передать свой идентификатор игрока**.

{% tabs %}
{% tab title="Unreal Engine" %}
Чтобы **подключиться из PIE (редактор)** во время разработки и тестирования нажмите клавишу тильды `~`  и введите `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="success" %}
Если дизайн вашей игры допускает период повторного подключения, ваш сервер может подождать перед обновлением слотов.
{% endhint %}

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

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

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

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

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

{% 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 %}

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

Политики масштабирования постоянно обновляют список ваших серверных экземпляров (обнаруженных развертываний), повторяя это каждые [`monitoring_interval`](#user-content-fn-9)[^9] . Каждая политика требует фильтр с использованием того же [синтаксиса фильтрации](#search-and-browse) что и игроки при поиске экземпляров — по региону, емкости или другим критериям.

Заданное вами [`minimum_active_instances`](#user-content-fn-10)[^10]  значение может рассматриваться как:

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

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

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

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

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

#### Резерв предварительного прогрева

Запускайте серверы заранее, до появления спроса игроков, если:

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

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

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

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

Политики запускают развертывания с [Частные пулы](/ru/learn/orkestraciya/chastnye-puly.md) (с Overflow to Cloud) или напрямую в Cloud.

Доступные параметры включают ([см. спецификацию 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-puly.md) - оставьте пустым для облака или укажите хосты в нужном регионе,
* [**теги**](/ru/learn/orkestraciya/deployments.md#dashboard-monitoring) - помечайте именем политики, чтобы позже находить развертывания, запущенные с этой политикой,
* [**переменные окружения**](/ru/learn/orkestraciya/deployments.md#custom-variables) - передавайте пользовательские параметры и секреты серверам,
* [**вебхуки**](/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">user_data</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="🌡️ Предварительный прогрев" %}
Запускайте развёртывания 10x до релиза в ожидании спроса. Копируйте для каждого региона.

<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">user_data</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="🔒 MMO" %}
Каждый регион добавляет развёртывания по мере того, как доступная ёмкость падает ниже порога.

<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">user_data</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">user_data</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 %}

{% tab title="❄️ Mesh-группа" %}
Одна политика на группу серверов. Игровой бэкенд запускает основной узел, который создаёт реплики. Каждый узел читает внедрённый идентификатор mesh-группы и ищет другие узлы для сетевого взаимодействия.

<pre class="language-json" data-title=""><code class="lang-json">{
<strong>  "name": "sb-meshgroup-pqyt8sxcb",
</strong><strong>  <a data-footnote-ref href="#user-content-fn-12">"filter"</a>: "metadata.policy_name eq 'sb-meshgroup-pqyt8sxcb'",
</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">user_data</a>": {
<strong>          "latitude": 41.881832,
</strong><strong>          "longitude": -87.623177
</strong>        }
      }
    ],
<strong>    "tags": ["sb-meshgroup-pqyt8sxcb"],
</strong>    "environment_variables": [
      {
<strong>        "key": "SB_SCALING_POLICY_NAME",
</strong><strong>        "value": "sb-meshgroup-pqyt8sxcb",
</strong>        "is_hidden": false
      },
      {
<strong>        "key": "SB_MESH_GROUP_ID",
</strong><strong>        "value": "pqyt8sxcb",
</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-24">"webhook_on_terminated"</a>: {
</strong>      "url": "https://my-webhook.com"
    }
  },
<strong>  <a data-footnote-ref href="#user-content-fn-25">"minimum_active_instances"</a>: 9
</strong>}
</code></pre>

{% endtab %}
{% endtabs %}

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

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

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

<pre class="language-json" data-title="sb-simple-example-v1-0-1.json"><code class="lang-json">{
	"version": "1.0.1",
	"server_instances": {
		"expiration_period": "1m",
		"<a data-footnote-ref href="#user-content-fn-26">индексы</a>": {
			"policy_name": "string",
			"name": "string"
		}
	},
	"server_instance_slots": {
		"<a data-footnote-ref href="#user-content-fn-26">индексы</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-0-1.json"><code class="lang-json">{
	"version": "1.0.1",
	"server_instances": {
		"expiration_period": "15s",
		"<a data-footnote-ref href="#user-content-fn-26">индексы</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-26">индексы</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-0-1.json"><code class="lang-json">{
	"version": "1.0.1",
	"server_instances": {
		"expiration_period": "15s",
		"<a data-footnote-ref href="#user-content-fn-26">индексы</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-26">индексы</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-0-1.json"><code class="lang-json">{
	"version": "1.0.1",
	"server_instances": {
		"expiration_period": "15s",
		"<a data-footnote-ref href="#user-content-fn-26">индексы</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-26">индексы</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 деталей экземпляра сервера или слота, см. [#api](#api "mention").
{% 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">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">200</td><td align="right">750</td><td align="right">2,000</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-запросов,
* **количество запросов на игрока** - более быстрые повторные попытки увеличивают нагрузку на сервис и потребляют ресурсы,
* **количество серверов** - больше серверов приводит к большему объёму хранимых данных и большему количеству API-запросов,
* **логика резервного повторного запроса клиента** - повторные попытки с задержкой и джиттером помогают распределять пики всплесков трафика,
* **средняя длительность матча** - более короткие сессии требуют более частого взаимодействия с сервер-браузером.

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

## 📗 API

**Рекомендуем использовать наш SDK для** [**Unreal Engine**](/ru/unreal-engine/developer-tools.md) **или** [**Unity**](/ru/unity/brauzer-serverov.md) **чтобы быстро начать с готовыми примерами.**

Игровые клиенты и выделенные серверы отправляют API-запросы на протяжении всего своего жизненного цикла в Server Browser.

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

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

{% file src="/files/597d4677aa9cdc5bddec091a1d4093cf7b7cb0d0" %}

Импортируйте спецификацию API в [веб-клиент API Scalar](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`  ответ, и ожидается, что он повторит попытку с увеличивающимся периодом ожидания.

Если политики масштабирования инициировали бы больше развёртываний, чем допустимый предел req/s вашей организации, ваш сервер-браузер будет автоматически повторять попытку на каждом интервале мониторинга, используя стратегию взвешенного циклического распределения на основе количества запланированных развёртываний, стремясь равномерно распределить доступную квоту развёртываний между всеми политиками масштабирования.

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

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

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

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

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

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

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

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

{% hint style="info" %}
**Последняя версия Server Browser — `1.0.0`** . Следите за [обновлениями и объявлениями](/ru/docs/release-notes.md).
{% 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]: уведомлять игровой бэкенд при остановке

[^25]: Сетка 3×3 = 9 серверов на мир

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