# 服务器浏览器

**欢迎来到 Edgegap Server Browser 公测版。** 我们希望你喜欢抢先体验我们新服务的机会，并通过我们 Discord 中的圆桌讨论帮助塑造它的未来。

Server Browser 是一项托管服务，适用于 [部署](/zh/learn/bian-pai/deployments.md#match-bound) 和 [持久化](/zh/learn/bian-pai/chi-jiu-hua.md) 服务器：

* **帮助玩家搜索并加入合适的服务器** ，依据容量、延迟或游戏参数；
* **预热新服务器** 以便按规模服务全球受众并避免令人沮丧的排队；
* **简化服务器运维** 包括更新、重启、持久化、网格化等。

{% hint style="success" %}
如果你想根据严格规则匹配玩家，而不允许选择服务器？请考虑 [匹配](/zh/learn/pi-pei.md).
{% endhint %}

<figure><img src="/files/67650f7374cd84f82abe602f7237e42ebe0f3a06" alt=""><figcaption></figcaption></figure>

## ✔️ 准备

### 流程与层级

<figure><img src="/files/f0ec3b2982968b574e907b650e12ae4068dce02b" alt=""><figcaption><p>Server Browser：流程与层级</p></figcaption></figure>

Server Browser 提供两项主要功能：

[#start-browsing](#start-browsing "mention") 与游戏客户端一起：

* 发现并找到合适的服务器实例，查看席位，并预留可用容量。
* 在实例席位中预留座位，获取连接详情，并连接到服务器。
* 使用以下方式验证来自部署的玩家连接 联邦身份[^1].
* 更新实例席位的可用容量和/或元数据，以修改发现条件。

[#automated-scaling](#automated-scaling "mention") （可选）与扩容策略一起：

* 监控可用的服务器实例、席位、容量——按区域和/或其他条件。
* 部署服务器以通过预热或即时扩容增加容量。
* 通过用于演示、更新、测试、QA、锦标赛等的特殊策略自动化运维。

{% hint style="info" %}
发布后， **你的服务器浏览器将需要 24/7 运行** 以确保全球各地的玩家都能加入服务器。
{% endhint %}

## ▶️ 开始浏览

了解服务器/玩家生命周期及其职责，以确保高效使用服务器。

### 验证身份

Server Browser 会自动生成两种类型的令牌：

* **服务器令牌** - 需要用于 [服务器 API](#server-lifecycle) 方法，可 [作为应用版本变量注入](/zh/learn/bian-pai/application-and-versions.md#injected-variables).
  * 授予对所有 API 方法的访问权限，适合测试、DevOps 或自定义编排。
* **客户端令牌** - 需要用于 [监控 API 和座位预留 API](#player-lifecycle) 供游戏客户端使用。
  * 我们建议将此令牌存储在第三方密钥库中，以便更轻松地轮换令牌。

### 发现实例

**新建** [部署](/zh/learn/bian-pai/deployments.md) **初始化时必须创建一个至少包含一个席位的新实例。**

{% hint style="info" %}
查看 [#automated-scaling](#automated-scaling "mention") 以了解扩容策略并自动开始部署。
{% endhint %}

**可选的自定义元数据参数** 用于玩家筛选、排序和浏览。

示例：

* 席位信息 - 队伍容量和队伍专属元数据（例如队伍名称），
* 名称和标签 - 可自定义、唯一、可读且可搜索的标签；
* 连接详情 - URL、IP、外部端口或其他参数；
* 兼容性数据 - 服务器版本或支持的客户端版本；
* 延迟限定信息 - 城市和区域标识，以及分配的 [Ping 信标](/zh/learn/bian-pai/ping-beacons.md) 详情；
* 游戏参数 - 关卡/场景/地图、游戏模式、难度、使用的模组；
* 任何其他可帮助玩家筛选并找到合适服务器的自定义参数。

{% hint style="info" %}
上面的元数据参数只是示例，你可以定义包括上述在内的任何参数。所有元数据参数都是可选的，有些实例可能不需要定义所有参数。
{% endhint %}

元数据支持字符串键和值，值可包含字符串、数字、布尔值或字符串数组。

{% hint style="success" %}
要序列化嵌套对象，可尝试在键中将其访问路径编码为 `"object.child.property"`.
{% endhint %}

服务器可以 **随时更新实例或席位元数据** 以修改其可发现性条件。

**服务器实例必须定期发送保活心跳** 以验证其持续可用性，并防止玩家加入已崩溃或离线的服务器。在配置的过期周期内若缺少心跳，将自动删除该实例及任何待处理的座位预留。

{% hint style="info" %}
查看 [持久化](/zh/learn/bian-pai/chi-jiu-hua.md) 用于管理持久化世界状态并 [应用和版本](/zh/learn/bian-pai/application-and-versions.md#active-caching) 用于更快部署。
{% endhint %}

### 搜索与浏览

玩家可以列出服务器实例并 [分页浏览结果](#pagination) 以找到他们想加入的服务器。要显示 ping（延迟）数据，请读取每个实例的 [Ping 信标](/zh/learn/bian-pai/ping-beacons.md) 详情并 [测量延迟](/zh/learn/bian-pai/ping-beacons.md#measuring-round-trip-time).

实例和席位可按可加入席位或 [已索引的元数据参数进行过滤](#configuration).

<table><thead><tr><th width="170">参数</th><th width="135">运算符</th><th>示例过滤器（基于简单示例）</th></tr></thead><tbody><tr><td><code>"joinable_seats"</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-4"><code>ne</code></a> 或 </p><p><a data-footnote-ref href="#user-content-fn-6"><code>lt</code></a>  或 <a data-footnote-ref href="#user-content-fn-7"><code>le</code></a> 或 </p><p><a data-footnote-ref href="#user-content-fn-8"><code>gt</code></a>  或 <a data-footnote-ref href="#user-content-fn-9"><code>ge</code></a></p></td><td><pre><code>?filter=<a data-footnote-ref href="#user-content-fn-3">joinable_seats gt 0</a>
&#x26;orderby=<a data-footnote-ref href="#user-content-fn-5">joinable_seats desc</a>
</code></pre></td></tr><tr><td><code>"string"</code><br>（元数据）</td><td><p><a data-footnote-ref href="#user-content-fn-2"><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-6"><code>lt</code></a>  或 <a data-footnote-ref href="#user-content-fn-7"><code>le</code></a> 或 </p><p><a data-footnote-ref href="#user-content-fn-8"><code>gt</code></a>  或 <a data-footnote-ref href="#user-content-fn-9"><code>ge</code></a>  或<br><code>包含</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;orderby=metadata.custom_name asc
</code></pre></td></tr><tr><td><p><code>"int"</code> ，或 <code>"float"</code></p><p>（元数据）</p></td><td><p><a data-footnote-ref href="#user-content-fn-2"><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-6"><code>lt</code></a>  或 <a data-footnote-ref href="#user-content-fn-7"><code>le</code></a> 或 </p><p><a data-footnote-ref href="#user-content-fn-8"><code>gt</code></a>  或 <a data-footnote-ref href="#user-content-fn-9"><code>ge</code></a>  </p></td><td><pre><code>?filter=metadata.xp_multiplier gt 1.0
&#x26;orderby=metadata.xp_multiplier desc
</code></pre></td></tr><tr><td><code>"bool"</code><br>（元数据）</td><td><a data-footnote-ref href="#user-content-fn-2"><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 %}

### 预留席位

在加入服务器之前，需要进行席位预留，以确保该实例提供足够的可用容量。预留可以包含一组玩家或单个玩家。

**超出席位可加入容量的预留将被自动拒绝** ([409 冲突](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Status/409)）。可加入席位是指尚未被其他玩家预留的任何可用席位。

联邦身份：玩家必须在预留中提供唯一的第三方玩家 ID。发送相同的 ID 一旦他们 [#connect-to-server](#connect-to-server "mention") 将允许服务器验证其身份。

一旦预留成功建立（[200 OK](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Status/200)），玩家应立即尝试连接。待处理的 **预留将在 30 秒后过期，除非它们已被** 你的服务器确认。

{% hint style="info" %}
服务器可以强制更改任何席位的容量，添加、删除或更新任何席位。 **如果任何待处理预留超出了新的可用席位容量，则给定席位的所有预留都将被移除。**
{% endhint %}

### 连接到服务器

当玩家找到合适的实例后，他们可以 **从元数据中获取所需的连接详情** （URL、IP、 [外部端口](/zh/learn/bian-pai/application-and-versions.md#port-mapping)）。一旦席位预留完成， **玩家即可连接到你部署中的游戏服务器并传递其玩家 ID**.

{% tabs %}
{% tab title="Unreal Engine" %}
要 **从 PIE（编辑器）连接** 在开发和测试期间，按下波浪号键 `~`  并输入 `open {URL}:{port}` 然后等待编辑器加载地图。

{% hint style="success" %}
如果连接失败或出现黑屏，请参阅我们的 [故障排除指南](/zh/xu-huan-yin-qing.md#troubleshooting-and-faq-1).
{% endhint %}
{% endtab %}

{% tab title="Unity" %}
要 **将你的 Unity 编辑器** 或 **游戏客户端** 连接到云部署，输入：

* **部署** **URL** 指向服务器的 IP，通常在 `NetworkManager`  组件中。
* **外部端口** 映射到 [服务器内部监听端口](https://docs.edgegap.com/learn/advanced-features/application-and-versions#port-mapping)，通常在 Transport 组件中。

{% hint style="success" %}
如果连接超时或遇到其他问题，请参阅我们的 [故障排除指南](/zh/unity.md#troubleshooting-and-faq-4).
{% endhint %}
{% endtab %}
{% endtabs %}

要验证新连接， **你的服务器必须发送批量预留确认** 请求，并附上所有新玩家的 ID，确认响应中会返回：

* 将已接受的玩家预留分配到其首选席位，
* 将已过期的玩家预留分配到其首选席位，
* 以及一个未知玩家 ID 列表。

你的 **服务器可以决定如何处理每组玩家** 以及是否允许或踢出/封禁过期或被拒绝的用户。每个 **实例的席位都必须立即更新新的可用席位数量** 以确保新的预留不会超出容量。

### 放弃服务器

当玩家离开时，服务器必须更新其分配的席位，以反映新的可用席位容量。

{% hint style="success" %}
如果你的游戏设计允许重连时间段，服务器可以在释放席位之前等待一段时间。
{% endhint %}

我们建议在没有玩家时停止服务器，以优化你的托管成本。在这样做之前等待几分钟，可以减少短暂空闲期间的重启次数。

阅读 [持久化](/zh/learn/bian-pai/chi-jiu-hua.md#recovery-objectives) 以防止令人沮丧的持久服务器回滚。

## 🚀 自动扩容

Server Browser 兼容多种自动扩容方式：

* **预热方式** - 严格使用 Server Browser 扩容策略启动服务器，
* **即时方式** - 通过 [匹配](/zh/learn/pi-pei.md) 和 [用 Server Browser 填充](#start-browsing),
* **自定义自动扩缩容器** - 通过自定义游戏后端和 [用 Server Browser 填充](#start-browsing).

以下指南将重点介绍 **使用扩容策略进行预热** 作为主要方法。

{% hint style="success" %}
了解如何在 [Unreal Engine](/zh/xu-huan-yin-qing.md#stop-deployments), [Unity](/zh/unity.md#stop-deployments)，或 [中使用 API 停止部署](/zh/docs/api/zhuan-yong-fu-wu-qi.md#delete-v1-self-stop-request_id-access_point_id) 以可靠地管理生命周期。
{% endhint %}

### 监控容量

扩容策略会持续刷新你的服务器实例列表（已发现的部署），每隔 [`monitoring_interval`](#user-content-fn-10)[^10] 。每个策略都可以包含一个使用相同 [筛选语法](#search-and-browse) 的过滤器，就像玩家搜索实例时一样——按区域、容量或其他条件。

你配置的 [`minimum_active_instances`](#user-content-fn-11)[^11]  数量可以被视为以下任一项：

* **固定容量** 你希望始终保持运行的部署数量，
* **预热待命** 部署缓冲，用于隐藏初始化延迟。

#### 固定容量

保持固定数量的服务器特别适用于具有 [持久化](/zh/learn/bian-pai/chi-jiu-hua.md)的游戏，尤其是当这些游戏允许玩家租用 [持久化](/zh/learn/bian-pai/chi-jiu-hua.md#community-servers).

这种策略配置有时也用于质量保证、锦标赛、封闭 Alpha、发行商演示或其他类型的限容量活动和运营。

{% hint style="info" %}
扩容策略可帮助你自动在运行中重启并回收崩溃或停止的服务器。
{% endhint %}

#### 预热待命

在玩家需求之前启动服务器，在以下情况下会更有优势：

* 发布重大版本或更新，并预期在短时间内迅速涌入大量玩家，
* 或者服务器初始化需要超过 30 秒（不包括部署时间），
* 或者游戏实现了需要复杂或循环网络依赖的网格化策略。

{% hint style="info" %}
使用匹配机制时，你需要 [深入了解](/zh/learn/pi-pei/matchmaker-in-depth.md#backfill-match) 在启动新部署之前利用这部分容量。
{% endhint %}

### 部署服务器

当被监控的服务器实例数量低于配置的活动实例最小值时，将自动启动新的部署。所有部署都会立即请求，并在 [`deployment_registration_period`](#user-content-fn-10)[^10]  经过后无限重试。

{% hint style="warning" %}
验证新的部署 [执行自动发现并创建实例](#discover-instance) 是否正确匹配你的策略过滤器，或者 **你的策略可能会无限循环并创建大量未使用的部署**!&#x20;
{% endhint %}

在为你的策略定义部署请求时，我们使用标准部署参数，允许在私有舰队中部署（并溢出到云端）或直接部署到云端：

* [**应用和版本**](/zh/learn/bian-pai/application-and-versions.md) - 构建版本、资源以及其他编排参数，
* **用户** - 用于首选 [服务器放置](/zh/learn/bian-pai/deployments.md#regional-standby),
* [**的单组坐标**](/zh/learn/bian-pai/si-you-jian-dui.md) 私有主机 ID
* [**标签**](/zh/learn/bian-pai/deployments.md#dashboard-monitoring) - 用策略名称打标签，以便日后找到使用该策略启动的部署，
* [**环境变量**](/zh/learn/bian-pai/deployments.md#custom-variables) - 向服务器传递自定义参数和密钥，
* [**webhook**](/zh/learn/bian-pai/deployments.md#webhooks-and-postbacks) - 将部署生命周期事件通知你的游戏后端（或匹配器），
* [**需要缓存位置**](/zh/learn/bian-pai/application-and-versions.md#active-caching) - 如果你只希望在缓存位置中获得更快的部署。

### 示例策略

按需测试和修改这些策略。大多数游戏会使用多个策略。

<details>

<summary>🍀 质量保证池（最小示例）</summary>

一个简单策略，用于始终保留一台服务器用于测试。

<pre class="language-json" data-title=""><code class="lang-json">{
  "name": "sb-qa-pool",
  <a data-footnote-ref href="#user-content-fn-12">"filter"</a>: "metadata.policy_name eq 'sb-qa-pool'",
  "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>": {
          "latitude": 41.881832,
          "longitude": -87.623177
        }
      }
    ],
    "tags": ["sb-qa-pool"],
    "environment_variables": [
      {
        "key": "SB_POLICY_NAME",
        "value": "sb-qa-pool",
        "is_hidden": false
      }
    ]
  },
  "minimum_active_instances": 1
}
</code></pre>

</details>

<details>

<summary>🌡️ 按区域预热发布</summary>

每个区域都会在发布前启动一个部署，以应对需求。

<pre class="language-json" data-title=""><code class="lang-json">{
  "name": "sb-v1.0.0-chicago",
  <a data-footnote-ref href="#user-content-fn-16">"filter"</a>: "joinable_seats gt 0 and metadata.policy_name eq 'sb-v1.0.0-chicago'",
  "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>": {
          "latitude": 41.881832,
          "longitude": -87.623177
        }
      }
    ],
    "tags": ["sb-v1.0.0-chicago"],
    "environment_variables": [
      {
        "key": "SB_POLICY_NAME",
        "value": "sb-v1.0.0-chicago",
        "is_hidden": false
      }
    ]
  },
  <a data-footnote-ref href="#user-content-fn-17">"minimum_active_instances"</a>: 10
}
</code></pre>

</details>

<details>

<summary>❄️ 服务器网格分组</summary>

每组服务器对应一条策略，游戏后端为每组添加新的策略。

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

</details>

<details>

<summary>🔑 社区服务器</summary>

每个服务器所有者对应一条策略，传入用于服务器身份验证的自定义密码。

<pre class="language-json" data-title=""><code class="lang-json">{
  "name": "sb-owner-jnjnc8mid",
  <a data-footnote-ref href="#user-content-fn-21">"filter"</a>: "metadata.policy_name eq 'sb-owner-jnjnc8mid'",
  "deployment_request": {
    <a data-footnote-ref href="#user-content-fn-22">"private_host_ids"</a>: ["alpha-north-america-95fab093"],
    "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>": {
          "latitude": 41.881832,
          "longitude": -87.623177
        }
      }
    ],
    "tags": ["community", "sb-owner-jnjnc8mid"],
    "environment_variables": [
      {
        "key": "SB_POLICY_NAME",
        "value": "sb-owner-jnjnc8mid",
        "is_hidden": false
      },
      {
        "key": "SB_SERVER_PASSWORD",
        "value": "password1234",
        "is_hidden": false
      }
    ],
    <a data-footnote-ref href="#user-content-fn-18">"webhook_on_ready"</a>: {
      "url": "https://my-webhook.com"
    },
    <a data-footnote-ref href="#user-content-fn-23">"webhook_on_error"</a>: {
      "url": "https://my-webhook.com"
    },
    <a data-footnote-ref href="#user-content-fn-24">"webhook_on_terminated"</a>: {
      "url": "https://my-webhook.com"
    }
  },
  "minimum_active_instances": 1
}
</code></pre>

</details>

<details>

<summary>🔒 区域锁定 MMO</summary>

每个区域会在可用容量低于阈值时增加部署。

<pre class="language-json" data-title=""><code class="lang-json">{
  "name": "sb-mmo-chicago",
  <a data-footnote-ref href="#user-content-fn-25">"filter"</a>: "joinable_seats gt 5 and metadata.policy_name eq 'sb-mmo-chicago'",
  "deployment_request": {
    <a data-footnote-ref href="#user-content-fn-22">"private_host_ids"</a>: ["alpha-north-america-95fab093"],
    "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>": {
          "latitude": 41.881832,
          "longitude": -87.623177
        }
      }
    ],
    "tags": ["sb-mmo-chicago"],
    "environment_variables": [
      {
        "key": "SB_POLICY_NAME",
        "value": "sb-mmo-chicago",
        "is_hidden": false
      }
    ],
    <a data-footnote-ref href="#user-content-fn-24">"webhook_on_terminated"</a>: {
      "url": "https://my-webhook.com"
    }
  },
  "minimum_active_instances": 3
}
</code></pre>

</details>

## ⚙️ 配置

Server Browser API 由在创建新的（或快速重启）Server Browser 时指定的 JSON 配置生成。你可以指定服务器和席位过期时间，以及自定义元数据：

{% tabs %}
{% tab title="🍀 简单示例" %}

<pre class="language-json" data-title="sb-simple-example-v0-0-5.json"><code class="lang-json">{
	"version": "0.0.5",
	"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": "1m"
	},
	"scaling_policies": {
		"monitoring_interval": "10s",
		"deployment_registration_period": "1m"
	}
}
</code></pre>

{% endtab %}

{% tab title="🎈 社交游戏" %}

<pre class="language-json" data-title="sb-social-example-v0-0-5.json"><code class="lang-json">{
	"version": "0.0.5",
	"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"
	}
}
</code></pre>

{% endtab %}

{% tab title="🤝 合作游戏" %}

<pre class="language-json" data-title="sb-cooperative-example-v0-0-5.json"><code class="lang-json">{
	"version": "0.0.5",
	"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"
	}
}
</code></pre>

{% endtab %}

{% tab title="⚔️ 竞技游戏" %}

<pre class="language-json" data-title="sb-competitive-example-v0-0-5.json"><code class="lang-json">{
	"version": "0.0.5",
	"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"
	}
}
</code></pre>

{% endtab %}
{% endtabs %}

{% hint style="info" %}
为了获得最佳性能，请避免为未用于筛选或排序的元数据指定索引。未索引的参数仍可通过服务器实例或席位详情 API 方法进行设置和读取，参见 [#api](#api "mention").
{% endhint %}

## ☁️ 托管集群

Server Browser 由 Edgegap 便捷地全天候 24/7 托管和管理。

选择最适合你目标的托管选项：

### 私有集群层级

一键升级到私有集群，即可受益于由 Edgegap 团队维护的高可用托管，并为公开发布的游戏提供 24/7 实时支持。

你的实例资源需求将取决于以下因素：

* **玩家数量** - 玩家越多，API 请求越多，
* **每位玩家的请求数量** - 更快的重试会增加服务负载并消耗资源，
* **服务器数量** - 更多服务器意味着存储更多数据和更多 API 请求，
* **客户端重试回退逻辑** - 使用带抖动的退避重试有助于分散流量峰值，
* **平均对局时长** - 更短的会话需要更频繁地与服务器浏览器交互。

## 📗 API

游戏客户端和专用服务器在其生命周期中会持续向 Server Browser 发送 API 请求。

{% file src="/files/326ba240134f83aafe919e52ceaad1cfc139cc1e" %}

导入 API 规范到 [Scalar API Web Client](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 的最新版本是 `0.0.5`** 。请关注更新和公告。
{% endhint %}

#### 0.0.5（2026 年 3 月 18 日）

* 引入 [#automated-scaling](#automated-scaling "mention") 和 [#example-policies](#example-policies "mention").
* 添加更多 [#configuration](#configuration "mention") 供你灵感参考的示例。
* 改进 [#flow-and-hierarchy](#flow-and-hierarchy "mention") 图示，让你更快上手。

#### 0.0.4（2026年1月5日）

* 进入公开测试阶段，新增 [服务器实例和槽位的筛选与排序](#search-and-browse)!

#### 0.0.3（2025年11月28日）

* Server Browser 服务的初始版本已在封闭测试阶段发布。
* 列出服务器、管理容量并获取连接详情。
* 支持使用云部署进行匹配会话，以及通过专用舰队实现始终在线。

[^1]: 第三方玩家标识

[^2]: 等于

[^3]: 查找有可用席位的实例

[^4]: 不等于

[^5]: 优先显示填充更满的实例

[^6]: 小于

[^7]: 小于或等于

[^8]: 大于

[^9]: 大于或等于

[^10]: 请参见配置

[^11]: 请参见示例策略

[^12]: * 固定容量
    * 假设实例通过注入变量在元数据中提供策略名称

[^13]: 替换为你自己的应用名称

[^14]: 替换为你自己的应用版本

[^15]: 芝加哥坐标

[^16]: * 当发现少于 10 个可加入实例时部署
    * 假设实例通过注入变量在元数据中提供策略名称

[^17]: 我们预计芝加哥区域至少有 10 个部署

[^18]: 准备就绪时通知游戏后端

[^19]: 停止时通知游戏后端

[^20]: 3x3 网格 = 每个世界 9 台服务器

[^21]: * 不监控容量
    * 假设实例通过注入变量在元数据中提供策略名称

[^22]: 如果有可用容量，优先使用私有舰队

[^23]: 部署失败时通知游戏后端

[^24]: 服务器重启时通知游戏后端

[^25]: * 当发现少于 3 个且可加入席位不超过 5 的实例时部署
    * 假设实例通过注入变量在元数据中提供策略名称

[^26]: 索引包含用于筛选或排序的自定义元数据参数


---

# Agent Instructions: 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/zh/learn/fu-wu-qi-liu-lan-qi.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.
