> 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/server-browser.md).

# Server Browser

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

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

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

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

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

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

<figure><img src="/files/96a599df5c2103cc6318a87085a3f561be54cddc" 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 %}

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

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

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

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, сведения о порте и местоположение.

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

* информация о слоте — ёмкость команды и метаданные, специфичные для команды (например, название команды),
* имя и теги — настраиваемые, уникальные, читаемые человеком и доступные для поиска метки;
* данные совместимости — версия сервера или поддерживаемые версии клиента;
* параметры задержки — идентификаторы города и региона, а также назначенные [Ping Beacons](/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/sokhranenie-sostoyaniya.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-2"><code>eq</code></a>  или <a data-footnote-ref href="#user-content-fn-3"><code>ne</code></a> или </p><p><a data-footnote-ref href="#user-content-fn-4"><code>lt</code></a>  или <a data-footnote-ref href="#user-content-fn-5"><code>le</code></a> или </p><p><a data-footnote-ref href="#user-content-fn-6"><code>gt</code></a>  или <a data-footnote-ref href="#user-content-fn-7"><code>ge</code></a>  или<br><code>содержит</code></p></td><td><pre><code>?$filter=metadata.custom_name contains 'моя игра'
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-2"><code>eq</code></a>  или <a data-footnote-ref href="#user-content-fn-3"><code>ne</code></a> или </p><p><a data-footnote-ref href="#user-content-fn-4"><code>lt</code></a>  или <a data-footnote-ref href="#user-content-fn-5"><code>le</code></a> или </p><p><a data-footnote-ref href="#user-content-fn-6"><code>gt</code></a>  или <a data-footnote-ref href="#user-content-fn-7"><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-2"><code>eq</code></a>  или <a data-footnote-ref href="#user-content-fn-3"><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 %}

#### Зарезервировать места

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

Федеративная идентификация: игроки должны указать уникальный идентификатор игрока стороннего сервиса в своём резервировании. Отправка того же ID после того, как они [#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 %}

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

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

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

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

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

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

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

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

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

* **метод предварительного прогрева** — запуск серверов исключительно с политиками масштабирования Server Browser,
* **метод just-in-time** — запуск через [Подбор матчей](/ru/learn/podbor-matchei.md) и [заполнение с помощью Server Browser](#allocate-capacity),
* **собственный автоскейлер** — запуск через собственный игровой backend и [заполнение с помощью 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-8)[^8] . Каждая политика требует фильтра с использованием того же [синтаксиса фильтрации](#search-and-browse) что и у игроков при поиске экземпляров — по региону, ёмкости или другим критериям.

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

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

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

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

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

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

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

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

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

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

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

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

Политики запускают развёртывания с [Частные флоты](/ru/learn/orkestraciya/chastnye-floty.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-floty.md) — оставьте пустым для облака или укажите хосты в нужном регионе,
* [**теги**](/ru/learn/orkestraciya/deployments.md#dashboard-monitoring) — пометьте именем политики, чтобы позже найти развёртывания, запущенные с этой политикой,
* [**переменные окружения**](/ru/learn/orkestraciya/deployments.md#custom-variables) — передавайте пользовательские параметры и секреты серверам,
* [**вебхуки**](/ru/learn/orkestraciya/deployments.md#webhooks-and-postbacks) — уведомляйте свой игровой backend (или матчмейкер) о событиях жизненного цикла развёртывания,
* [**требовать кэшированные местоположения**](/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-11">"filter"</a>: "metadata.policy_name eq 'sb-qa-pool'",
</strong>  "deployment_request": {
    "private_host_ids": [],
    "application": <a data-footnote-ref href="#user-content-fn-12">"my-game-server"</a>,
    "version": <a data-footnote-ref href="#user-content-fn-13">"2024.01.30-16.23.00-UTC"</a>,
    "users": [
      {
        "user_type": "geo_coordinates",
        "<a data-footnote-ref href="#user-content-fn-14">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-15">"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-12">"my-game-server"</a>,
    "version": <a data-footnote-ref href="#user-content-fn-13">"2024.01.30-16.23.00-UTC"</a>,
    "users": [
      {
        "user_type": "geo_coordinates",
        "<a data-footnote-ref href="#user-content-fn-14">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-16">"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-17">"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-18">"private_host_ids"</a>: ["alpha-north-america-95fab093"],
</strong>    "application": <a data-footnote-ref href="#user-content-fn-12">"my-game-server"</a>,
    "version": <a data-footnote-ref href="#user-content-fn-13">"2024.01.30-16.23.00-UTC"</a>,
    "users": [
      {
        "user_type": "geo_coordinates",
        "<a data-footnote-ref href="#user-content-fn-14">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-19">"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-20">"filter"</a>: "metadata.policy_name eq 'sb-owner-jnjnc8mid'",
</strong>  "deployment_request": {
<strong>    <a data-footnote-ref href="#user-content-fn-18">"private_host_ids"</a>: ["alpha-north-america-95fab093"],
</strong>    "application": <a data-footnote-ref href="#user-content-fn-12">"my-game-server"</a>,
    "version": <a data-footnote-ref href="#user-content-fn-13">"2024.01.30-16.23.00-UTC"</a>,
    "users": [
      {
        "user_type": "geo_coordinates",
        "<a data-footnote-ref href="#user-content-fn-14">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-21">"webhook_on_ready"</a>: {
</strong>      "url": "https://my-webhook.com"
    },
<strong>    <a data-footnote-ref href="#user-content-fn-22">"webhook_on_error"</a>: {
</strong>      "url": "https://my-webhook.com"
    },
<strong>    <a data-footnote-ref href="#user-content-fn-19">"webhook_on_terminated"</a>: {
</strong>      "url": "https://my-webhook.com"
    }
  },
  "minimum_active_instances": 1
}
</code></pre>

{% endtab %}

{% tab title="❄️ Mesh-группа" %}
Одна политика для группы серверов. Игровой бэкенд запускает основной узел, который создает реплики. Каждый узел считывает внедренный ID 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-11">"filter"</a>: "metadata.policy_name eq 'sb-meshgroup-pqyt8sxcb'",
</strong>  "deployment_request": {
    "private_host_ids": [],
    "application": <a data-footnote-ref href="#user-content-fn-12">"my-game-server"</a>,
    "version": <a data-footnote-ref href="#user-content-fn-13">"2024.01.30-16.23.00-UTC"</a>,
    "users": [
      {
        "user_type": "geo_coordinates",
        "<a data-footnote-ref href="#user-content-fn-14">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-21">"webhook_on_ready"</a>: {
</strong>      "url": "https://my-webhook.com"
    },
<strong>    <a data-footnote-ref href="#user-content-fn-23">"webhook_on_terminated"</a>: {
</strong>      "url": "https://my-webhook.com"
    }
  },
<strong>  <a data-footnote-ref href="#user-content-fn-24">"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-0.json"><code class="lang-json">{
	"version": "1.0.0",
	"server_instances": {
		"expiration_period": "1m",
		"<a data-footnote-ref href="#user-content-fn-25">индексы</a>": {
			"policy_name": "string",
			"name": "string"
		}
	},
	"server_instance_slots": {
		"<a data-footnote-ref href="#user-content-fn-25">индексы</a>": {}
	},
	"seat_reservations": {
		"expiration_period": "30s"
	},
	"scaling_policies": {
		"monitoring_interval": "10s",
		"deployment_registration_period": "1m"
	}
}
</code></pre>

{% endtab %}

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

<pre class="language-json" data-title="sb-social-example-v1-0-0.json"><code class="lang-json">{
	"version": "1.0.0",
	"server_instances": {
		"expiration_period": "15s",
		"<a data-footnote-ref href="#user-content-fn-25">индексы</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-25">индексы</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"
	}
}
</code></pre>

{% endtab %}

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

<pre class="language-json" data-title="sb-cooperative-example-v1-0-0.json"><code class="lang-json">{
	"version": "1.0.0",
	"server_instances": {
		"expiration_period": "15s",
		"<a data-footnote-ref href="#user-content-fn-25">индексы</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-25">индексы</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"
	}
}
</code></pre>

{% endtab %}

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

<pre class="language-json" data-title="sb-competitive-example-v1-0-0.json"><code class="lang-json">{
	"version": "1.0.0",
	"server_instances": {
		"expiration_period": "15s",
		"<a data-footnote-ref href="#user-content-fn-25">индексы</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-25">индексы</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"
	}
}
</code></pre>

{% endtab %}
{% endtabs %}

{% hint style="info" %}
Для наилучшей производительности избегайте указания индексов для метаданных, не используемых для фильтрации или сортировки. Нейндексированные параметры по-прежнему можно задавать и считывать с помощью методов API сведений об экземпляре сервера или слоте, см. [#api](#api "mention").
{% endhint %}

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

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

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

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

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

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

* **количество игроков** - больше игроков приводит к большему числу API-запросов,
* **число запросов на игрока** - более частые повторы повышают нагрузку на сервис и потребляют ресурсы,
* **количество серверов** - больше серверов приводит к большему объему хранимых данных и большему числу API-запросов,
* **логика резервного повторного запроса клиента** - повторные попытки с джиттерным backoff помогают распределять пики всплесков трафика,
* **средняя длительность матча** - более короткие сессии требуют более частого взаимодействия с Server Browser.

## 📗 API

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

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

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

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

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

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

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

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

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

{% 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]: * разворачивается, когда найдено менее 10 доступных экземпляров для присоединения
    * предполагает, что экземпляры указывают имя политики в метаданных из внедрённой переменной

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

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

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

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

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

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

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

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

[^24]: сетка 3x3 = 9 серверов на мир

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


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.edgegap.com/ru/learn/server-browser.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
