# 服务器浏览器

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

Server Browser 是一项托管服务，适用于 [#match-bound](https://docs.edgegap.com/zh/bian-pai/deployments#match-bound "mention") 和 [持久化](https://docs.edgegap.com/zh/learn/bian-pai/chi-jiu-hua) 服务器：

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

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

<figure><img src="https://3334189208-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FsR0dHSFv9ymoC0DO5G8J%2Fuploads%2FwKrq9tLaamRoM6vSLXZu%2Fimage.png?alt=media&#x26;token=83756c6f-d413-4ac1-988e-b90e7fa7a0a6" alt=""><figcaption></figcaption></figure>

## ✔️ 准备

### 流程与层级

<figure><img src="https://3334189208-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FsR0dHSFv9ymoC0DO5G8J%2Fuploads%2Fnwlt2Ot2ahlyLvI7kdGx%2Fimage.png?alt=media&#x26;token=14b5a6c8-48c8-4f23-a50a-0783acab14e3" 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) 方法，可 [作为应用版本变量注入](https://docs.edgegap.com/zh/bian-pai/application-and-versions#injected-variables).
  * 授予对所有 API 方法的访问权限，适合测试、DevOps 或自定义编排。
* **客户端令牌** - 需要用于 [监控 API 和座位预留 API](#player-lifecycle) 供游戏客户端使用。
  * 我们建议将此令牌存储在第三方密钥库中，以便更轻松地轮换令牌。

### 发现实例

**新建** [deployments](https://docs.edgegap.com/zh/learn/bian-pai/deployments "mention") **初始化时必须创建一个至少包含一个席位的新实例。**

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

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

示例：

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

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

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

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

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

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

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

### 搜索与浏览

玩家可以列出服务器实例并 [分页浏览结果](#pagination) 以找到他们想加入的服务器。要显示 ping（延迟）数据，请读取每个实例的 [ping-beacons](https://docs.edgegap.com/zh/learn/bian-pai/ping-beacons "mention") 详情并 [测量延迟](https://docs.edgegap.com/zh/bian-pai/ping-beacons#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、 [外部端口](https://docs.edgegap.com/zh/bian-pai/application-and-versions#port-mapping)）。一旦席位预留完成， **玩家即可连接到你部署中的游戏服务器并传递其玩家 ID**.

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

{% hint style="success" %}
如果连接失败或出现黑屏，请参阅我们的 [故障排除指南](https://docs.edgegap.com/zh/xu-huan-yin-qing#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" %}
如果连接超时或遇到其他问题，请参阅我们的 [故障排除指南](https://docs.edgegap.com/zh/unity#troubleshooting-and-faq-4).
{% endhint %}
{% endtab %}
{% endtabs %}

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

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

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

### 放弃服务器

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

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

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

阅读 [#recovery-objectives](https://docs.edgegap.com/zh/bian-pai/chi-jiu-hua#recovery-objectives "mention") 以防止令人沮丧的持久服务器回滚。

## 🚀 自动扩容

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

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

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

{% hint style="success" %}
了解如何在 [Unreal Engine](https://docs.edgegap.com/zh/xu-huan-yin-qing#stop-deployments), [Unity](https://docs.edgegap.com/zh/unity#stop-deployments)，或 [中使用 API 停止部署](https://docs.edgegap.com/zh/docs/api/zhuan-yong-fu-wu-qi#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]  数量可以被视为以下任一项：

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

#### 固定容量

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

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

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

#### 预热待命

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

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

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

### 部署服务器

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

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

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

* [**应用和版本**](https://docs.edgegap.com/zh/learn/bian-pai/application-and-versions) - 构建版本、资源以及其他编排参数，
* **用户** - 用于首选 [服务器放置](https://docs.edgegap.com/zh/bian-pai/deployments#regional-standby),
* [**的单组坐标**](https://docs.edgegap.com/zh/learn/bian-pai/si-you-ji-qun) 私有主机 ID
* [**标签**](https://docs.edgegap.com/zh/bian-pai/deployments#dashboard-monitoring) - 用策略名称打标签，以便日后找到使用该策略启动的部署，
* [**环境变量**](https://docs.edgegap.com/zh/bian-pai/deployments#custom-variables) - 向服务器传递自定义参数和密钥，
* [**webhook**](https://docs.edgegap.com/zh/bian-pai/deployments#webhooks-and-postbacks) - 将部署生命周期事件通知你的游戏后端（或匹配器），
* [**需要缓存位置**](https://docs.edgegap.com/zh/bian-pai/application-and-versions#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="<https://3334189208-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FsR0dHSFv9ymoC0DO5G8J%2Fuploads%2F0auyzkkQfLfNRgzKbWMn%2Fedgegap-server-browser-005.yaml?alt=media&token=84669896-e7b9-4415-8d66-131badb3fff5>" %}

导入 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]: 索引包含用于筛选或排序的自定义元数据参数
