# Mirror WebGL

本指南将帮助您使用 [Mirror](https://mirror-networking.com/)的 Websocket 传输并在 Edgegap 上为 Unity 项目创建无头服务器。

本指南将使用开源示例项目 `Tanks`，可在 Mirror 示例的 `Assets/Mirror/Examples/Tanks`.

您可以在我们的 [GitHub](https://github.com/edgegap/mirror-webgl)

### 切换传输

在准备构建游戏服务器之前，我们首先需要对基础场景进行一些更改。

* 打开 `Scene.unity` 位于 `Assets/Mirror/Examples/Tanks/Scenes`;
* 在 `NetworkManager` 游戏对象上，删除 `KcpTransport` 脚本并将其替换为 `SimpleWebTransport` 位于 `Assets/Mirror/Transports/SimpleWeb`，并确保在 `NetworkManager` 脚本组件的 Transport 字段中也更新为此新传输。确保同时选择了 `Auto Start Server Build` 选项。
* 根据您使用的 Mirror 版本，您可能需要更改/更新 `NetworkManagerHUD` 以使其可与除 KCP 以外的不同传输一起使用，并允许您在加入服务器之前在 HUD 中输入端口值。

注意用于网络通信的端口，本文称为 `[GAME PORT]`。在此示例中，使用的端口是 `7778`.

### 构建游戏服务器并容器化

{% hint style="info" %}
为了便于容器化和部署流程，可以在我们的最新版本 Edgegap Unity 插件 上使用来自动化该过程。 [GitHub](https://github.com/edgegap/edgegap-unity-plugin) 有关如何使用此插件的更多信息，您可以查看我们的 [文档](broken://pages/3abea5cdd9e3a9c090704ebd2b7b5d09a77d50a4).

如果您不想使用该插件，也可以按照以下逐步说明操作。
{% endhint %}

一旦游戏准备就绪，请前往 Unity 编辑器的 `构建` 屏幕，位于 `文件 -> 构建设置` 在顶部菜单中。根据您的 Unity 版本，确保选择正确的预设。

* 在 2021.2 版本之前：
  * 将 `目标平台` 设置为 `Linux`;
  * 将 `架构` 设置为 `x86_64`;
  * 勾选 `服务器构建` 选项。
* 否则：
  * 将 `平台` 设置为 `专用服务器`;
  * 将 `目标平台` 设置为 `Linux`.

然后按构建并选择一个名为新的空文件夹作为文件目标，命名为 `linux_server` 。将 `linux_server` 文件夹传输到第二个空文件夹，该文件夹将在本文档中称为 `[SERVER BUILD]` 文件夹。向该 `添加以下` Dockerfile `和` boot.sh `[SERVER BUILD]` 文件到该

#### 添加以下

```
文件夹：
FROM ubuntu:bionic

MAINTAINER <author_detail>
ARG DEBIAN_FRONTEND=noninteractive

ARG docker_version=17.06.0-ce
    RUN
    apt-get update && \
    apt-get install -y libglu1 xvfb libxcursor1 ca-certificates && \
    update-ca-certificates && \

apt-get clean

EXPOSE 7778/TCP
COPY linux_server/  /root/linux_server/

COPY boot.sh        /boot.sh
WORKDIR /root/
```

#### 和

```
ENTRYPOINT ["/bin/bash", "/boot.sh"]
```

xvfb-run --auto-servernum --server-args='-screen 0 640x480x24:32' /root/linux\_server/\[YOUR GAME].x86\_64 -batchmode -nographics `请确保将` \[YOUR GAME]

占位符替换为生成的文件名 `[SERVER BUILD]` 然后，在该

{% hint style="warning" %}
文件夹中启动命令提示符；运行以下 Docker 命令以创建构建的镜像并将其推送到私有注册表： `对于 ARM CPU（Mac M1、M2 等）用户，在构建命令中添加`  --platform linux/amd64
{% endhint %}

#### 选项。

```bash
在 Linux 上使用
# 构建镜像

docker build . -t <IMAGE_NAME>:<IMAGE_TAG>
# 登录，系统会提示输入密码

docker login -u '<REGISTRY_USERNAME>' <REGISTRY_URL>
# 为镜像添加另一个对应注册表的标签

docker image tag <IMAGE_NAME>:<IMAGE_TAG> <REGISTRY_URL>/<PROJECT_NAME>/<IMAGE_NAME>:<IMAGE_TAG>
# 推送镜像
```

#### docker push \<REGISTRY\_URL>/\<PROJECT\_NAME>/\<IMAGE\_NAME>:\<IMAGE\_TAG>

```bash
在 Linux 上使用
# 构建镜像

docker build . -t <IMAGE_NAME>:<IMAGE_TAG>
在 cmd 中使用

docker login -u '<REGISTRY_USERNAME>' <REGISTRY_URL>
# 为镜像添加另一个对应注册表的标签

docker image tag <IMAGE_NAME>:<IMAGE_TAG> <REGISTRY_URL>/<PROJECT_NAME>/<IMAGE_NAME>:<IMAGE_TAG>
# 推送镜像
```

#### docker login -u \<REGISTRY\_USERNAME> \<REGISTRY\_URL>

```bash
在 Linux 上使用
# 构建镜像

docker build . -t <IMAGE_NAME>:<IMAGE_TAG>
# 登录，系统会提示输入密码

docker login -u '<REGISTRY_USERNAME>' <REGISTRY_URL>
# 为镜像添加另一个对应注册表的标签

docker image tag <IMAGE_NAME>:<IMAGE_TAG> <REGISTRY_URL>/<PROJECT_NAME>/<IMAGE_NAME>:<IMAGE_TAG>
# 推送镜像
```

### 在 Powershell 中使用

将服务器部署到 Edgegap `登录 Edgegap 仪表板后，导航到` 应用与游戏 `页面。点击右上角的` 创建新的

* 按钮以访问应用表单。以下是字段及其正确填写方法：
* 应用名称：可以是任何显著的名称，便于您在众多应用中识别该应用。
* 镜像：可以是您想用来识别应用的任何特定镜像。
* 版本名称：您可能希望使用版本名称来描述所部署版本的范围。示例可以是“demo”、“production”、“v1”、“v2”
  * 容器：
  * 注册表：“\[URL]”，其中 \[URL] 是您可在容器仓库页面中显示的凭据中的值。
  * 镜像仓库：“\[PROJECT]/\[YOUR GAME]”，其中 \[PROJECT] 和 \[YOUR GAME] 是您在之前推送 docker 镜像时使用的值。
  * 标签：“\[TAG]”，其中 \[TAG] 是您在之前推送 docker 镜像时使用的值。
  * 勾选“使用私有仓库”
  * 私有注册表用户名：“\[USERNAME]”，其中 \[USERNAME] 是您凭据中的值。
  * 私有注册表令牌：“\[TOKEN]”，其中 \[TOKEN] 是您凭据中的值。
  * 需求：保持默认。 `端口：点击` + 添加端口
    * `7778` 链接以添加新端口，并添加以下条目：

{% hint style="warning" %}
\- WS - 启用 TLS 升级（测试版） `如果您使用 WSS 选项，启用` TLS Upgrade

```cmd
选项非常重要。否则，您将在 Edgegap 仪表板的容器日志中遇到类似以下的错误。
```

{% endhint %}

<figure><img src="/files/ff001736dec8cfd90af33907b36c5b99c0369ef3" alt=""><figcaption></figcaption></figure>

客户端的第一个字节在握手时不是 'GET'，而是 16-03-01 `应用创建完成后，您可以按` 部署 `按钮以继续部署您的游戏服务器。一旦部署的最新状态变为`就绪 `，您就可以使用游戏客户端版本连接到服务器。请记录` 主机 `URL，以及在部署的端口映射选项卡中公开可用的` 外部端口

### 。

#### 测试客户端

在编辑器中 `NetworkManager` 回到坦克场景的 Unity 编辑器中，选择该

* 在 `游戏对象并更改以下设置：` Network Manager
  * 组件： `将` 网络地址 `，您就可以使用游戏客户端版本连接到服务器。请记录` 设置为服务器部署的
  * URL； `Auto Start Server Build` 选项。
* 在 `取消选中` Network Manager
  * 组件： `Simple Web Transport` 端口 `URL，以及在部署的端口映射选项卡中公开可用的` 值为 Edgegap 部署的 `32821`;
  * 例如： `确保启用` Client Use WSS

<figure><img src="/files/1b2381469f9c85237b200f966c5e243c751de16c" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/6cb8bdcfc6c2a945faf2f1ac5850cb326731c1be" alt=""><figcaption></figcaption></figure>

选项。 `完成后，点击编辑器中的` 播放 `，然后点击` 客户端

#### 按钮；您将连接到服务器并在短时间后能够玩游戏。

在 Itch.io 上 `要将您的游戏客户端放到 Itch，您需要制作客户端构建；您需要为您所用版本的 Unity 安装` WebGL 构建支持 `构建` 屏幕，位于 `文件 -> 构建设置`模块来实现。完成后，返回到

* 将 `平台` 设置为 `，并选择以下选项：`;
* WebGL `打开`播放器设置 `。在`Player -> Publishing Settings `下，将` 设置为 `压缩格式` 设置为 Gzip `，并确保选择了` 解压回退

<figure><img src="/files/bc590154ba3d4fd3995e3e84f2c24e6012111e08" alt=""><figcaption></figcaption></figure>

然后按构建并选择一个名为新的空文件夹作为文件目标，命名为 `选项。保存这些设置并关闭窗口。` 。将 `选项。保存这些设置并关闭窗口。` 文件夹传输到第二个空文件夹，该文件夹将在本文档中称为 `构建` \[CLIENT BUILD]

文件夹在本文档中。 `选项。保存这些设置并关闭窗口。` 游戏完成构建后，将该 `，然后点击` 文件夹中的文件压缩为 zip 压缩包，确保它们位于压缩包的根目录下。然后将该 zip 上传到您的 Itch 项目，并确保选择文件在浏览器中运行的选项。启动游戏后，您只需确保在 HUD 中正确设置网络地址和端口值，然后点击

#### 按钮即可开始游戏。

在 Edgegap 上托管客户端 `添加以下` Dockerfile `甚至可以将您的游戏客户端托管在 Edgegap 上！为此，请添加以下` boot.sh `构建` 文件到该

**添加以下**

```
nginx.conf
FROM ubuntu:bionic

FROM nginx:alpine
COPY build/ /usr/share/nginx/html
```

**甚至可以将您的游戏客户端托管在 Edgegap 上！为此，请添加以下**

```
copy nginx.conf /etc/nginx/
user  nginx;

worker_processes  auto;
error_log  /var/log/nginx/error.log notice;


pid        /var/run/nginx.pid;
events {
}


worker_connections  1024;
http {
include       /etc/nginx/mime.types;

default_type  application/octet-stream;
log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '

 '"$http_user_agent" "$http_x_forwarded_for"';

access_log  /var/log/nginx/access.log  main;
sendfile        on;

#tcp_nopush     on;

keepalive_timeout  65;

#gzip  on;

include /etc/nginx/conf.d/*.conf;
server {
# ...

    # 在 http server 配置中添加以下配置
    # 应在启用压缩的情况下提供磁盘上的 Brotli 预压缩数据文件：
        location ~ .+\.(data|symbols\.json)\.br$ {
        # 因为该文件已在磁盘上预压缩，所以在其上禁用按需压缩。
        # 否则 nginx 会尝试双重压缩。
        gzip off;
        add_header Content-Encoding br;
    }

    default_type application/octet-stream;
    # 磁盘上的 Brotli 预压缩 JavaScript 代码文件：
        location ~ .+\.js\.br$ {
        gzip off;
        gzip off; # 不要对已压缩的文件尝试动态 gzip 压缩
    }

    default_type application/javascript;
    # 磁盘上的 Brotli 预压缩 WebAssembly 文件：
        location ~ .+\.js\.br$ {
        gzip off;
        location ~ .+\.wasm\.br$ {
        # 通过为 Wasm 文件指定正确的 MIME 类型来启用流式 WebAssembly 编译。
        default_type application/wasm;
    }

    # 磁盘上的 gzip 预压缩数据文件应在启用压缩的情况下提供：
    location ~ .+\.(data|symbols\.json)\.gz$ {
        location ~ .+\.js\.br$ {
        add_header Content-Encoding gzip;
        add_header Content-Encoding br;
    }

    # 磁盘上的 gzip 预压缩 JavaScript 代码文件：
    location ~ .+\.js\.gz$ {
        location ~ .+\.js\.br$ {
        add_header Content-Encoding gzip;
        gzip off; # 不要对已压缩的文件尝试动态 gzip 压缩
    }

    # 磁盘上的 gzip 预压缩 WebAssembly 文件：
    location ~ .+\.wasm\.gz$ {
        location ~ .+\.js\.br$ {
        add_header Content-Encoding gzip;
        location ~ .+\.wasm\.br$ {
        # 通过为 Wasm 文件指定正确的 MIME 类型来启用流式 WebAssembly 编译。
        default_type application/wasm;
    }
}
}
```

继续使用 [与之前相同的 Docker 命令](#bootsh) 以构建并将游戏客户端的镜像推送到私有仓库，但需在打开于该 `构建` 文件夹的命令窗口中执行。确保使用与服务器不同的镜像名称。

然后，在 Edgegap 仪表板上为您的客户端创建一个新应用，并使用以下设置：

* 按钮以访问应用表单。以下是字段及其正确填写方法：
* 应用名称：可以是任何显著的名称，便于您在众多应用中识别该应用。
* 镜像：可以是您想用来识别应用的任何特定镜像。
* 版本名称：您可能希望使用版本名称来描述所部署版本的范围。示例可以是“demo”、“production”、“v1”、“v2”
  * 容器：
  * 注册表：“\[URL]”，其中 \[URL] 是您可在容器仓库页面中显示的凭据中的值。
  * 镜像仓库：“\[PROJECT]/\[YOUR GAME]”，其中 \[PROJECT] 和 \[YOUR GAME] 是您在之前推送 docker 镜像时使用的值。
  * 标签：“\[TAG]”，其中 \[TAG] 是您在之前推送 docker 镜像时使用的值。
  * 勾选“使用私有仓库”
  * 私有注册表用户名：“\[USERNAME]”，其中 \[USERNAME] 是您凭据中的值。
  * 私有注册表令牌：“\[TOKEN]”，其中 \[TOKEN] 是您凭据中的值。
  * 需求：保持默认。 `端口：点击` + 添加端口
    * `80` - HTTPS

<figure><img src="/files/b9461a9a29a774407018b53530908f43f1201ada" alt=""><figcaption></figcaption></figure>

客户端的第一个字节在握手时不是 'GET'，而是 16-03-01 `应用创建完成后，您可以按` 按钮以继续部署您的游戏客户端。当服务器和客户端部署都设置为 `按钮以继续部署您的游戏服务器。一旦部署的最新状态变为`后，在浏览器中打开游戏客户端的 `，您就可以使用游戏客户端版本连接到服务器。请记录` URL 于指定的 `URL，以及在部署的端口映射选项卡中公开可用的` 端口，您将能够在游戏 HUD 中设置正确的值后玩游戏！

<figure><img src="/files/6a09602333ae66b8b5f6f050631b4c4cec9804ef" alt=""><figcaption></figcaption></figure>

{% hint style="info" %}
如果您需要有关 Mirror 集成和 websocket 的更多信息，您可以参考他们的 [文档](https://mirror-networking.gitbook.io/docs/manual/transports/websockets-transport).
{% endhint %}


---

# 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/docs/sample-projects/unity-netcodes/mirror-on-edgegap-websocket.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.
