# Mirror WebGL

Это руководство поможет вам использовать [Mirror](https://mirror-networking.com/)Websocket Transport и создать безголовый сервер на Edgegap для проекта Unity.

В этом руководстве будет использован открытый пример проекта `Tanks`, доступный в примерах Mirror в каталоге `Assets/Mirror/Examples/Tanks`.

Вы можете найти финальную версию этого примера на нашем [GitHub](https://github.com/edgegap/mirror-webgl)

### Смена транспорта

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

* Откройте `Scene.unity` расположенную в `Assets/Mirror/Examples/Tanks/Scenes`;
* В `NetworkManager` gameObject удалите `KcpTransport` скрипт и замените его на `SimpleWebTransport` расположенную в `Assets/Mirror/Transports/SimpleWeb`, также убедитесь, что обновили поле Transport у `NetworkManager` компонента скрипта на этот новый транспорт. Также убедитесь, что опция `Auto Start Server Build` выбрана.
* В зависимости от вашей версии Mirror вам возможно потребуется изменить/обновить `NetworkManagerHUD` чтобы он работал с транспортами, отличными от KCP, а также чтобы вы могли вводить значение порта в HUD перед подключением к серверу.

Обратите внимание на порт, используемый для сетевых коммуникаций, который в тексте обозначается как `[GAME PORT]`. В этом случае используется порт `7778`.

### Сборка серверa игры и контейнеризация

{% hint style="info" %}
Чтобы упростить процесс контейнеризации и деплоя, можно использовать последнюю версию плагина Edgegap для Unity на нашем [GitHub](https://github.com/edgegap/edgegap-unity-plugin) для автоматизации процесса. Для получения дополнительной информации о том, как использовать этот плагин, вы можете ознакомиться с нашей [документацией](broken://pages/8f2a97be56c6cb22e241d0ea675b0c2aafba8497).

Если вы предпочитаете, вы также можете следовать этим пошаговым инструкциям.
{% endhint %}

Когда игра будет готова, перейдите на `Экран сборки` редактора Unity, в меню `File -> Build Settings` в верхнем меню. Убедитесь, что выбрали правильные пресеты в зависимости от вашей версии Unity.

* До версии 2021.2:
  * Установите `Target Platform` в `Linux`;
  * Установите `Architecture` в `x86_64`;
  * Отметьте опцию `Server Build` .
* В противном случае:
  * Установите `Platform` в `Dedicated Server`;
  * Установите `Target Platform` в `Linux`.

Затем нажмите собрать и выберите новую пустую папку с именем `linux_server` в качестве места назначения файлов. Перенесите папку `linux_server` в другую пустую папку, которая в этом документе будет называться `[SERVER BUILD]` папкой. Добавьте следующие `Dockerfile` и `boot.sh` файлы в эту `[SERVER BUILD]` папку:

#### Dockerfile

```
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"]
```

#### 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]` ; Выполните следующие команды Docker, чтобы создать образ вашей сборки и отправить его в приватный реестр:

{% hint style="warning" %}
Для пользователей ARM CPU (Mac M1, M2 и т.д.) добавьте `--platform linux/amd64`  опцию к вашей команде сборки.
{% endhint %}

#### Использование Linux

```bash
# build the image
docker build . -t <IMAGE_NAME>:<IMAGE_TAG>

# login, a prompt will ask the password
docker login -u '<REGISTRY_USERNAME>' <REGISTRY_URL>

# add another tag to your image corresponding to the registry
docker image tag <IMAGE_NAME>:<IMAGE_TAG> <REGISTRY_URL>/<PROJECT_NAME>/<IMAGE_NAME>:<IMAGE_TAG>

#push the image
docker push <REGISTRY_URL>/<PROJECT_NAME>/<IMAGE_NAME>:<IMAGE_TAG>
```

#### Использование cmd

```bash
# build the image
docker build . -t <IMAGE_NAME>:<IMAGE_TAG>

# login, a prompt will ask the password
docker login -u <REGISTRY_USERNAME> <REGISTRY_URL>

# add another tag to your image corresponding to the registry
docker image tag <IMAGE_NAME>:<IMAGE_TAG> <REGISTRY_URL>/<PROJECT_NAME>/<IMAGE_NAME>:<IMAGE_TAG>

#push the image
docker push <REGISTRY_URL>/<PROJECT_NAME>/<IMAGE_NAME>:<IMAGE_TAG>
```

#### Использование Powershell

```bash
# build the image
docker build . -t <IMAGE_NAME>:<IMAGE_TAG>

# login, a prompt will ask the password
docker login -u '<REGISTRY_USERNAME>' <REGISTRY_URL>

# add another tag to your image corresponding to the registry
docker image tag <IMAGE_NAME>:<IMAGE_TAG> <REGISTRY_URL>/<PROJECT_NAME>/<IMAGE_NAME>:<IMAGE_TAG>

#push the image
docker push <REGISTRY_URL>/<PROJECT_NAME>/<IMAGE_NAME>:<IMAGE_TAG>
```

### Развертывание сервера на Edgegap

После входа в панель управления Edgegap перейдите на страницу `Applications & Games` . Нажмите кнопку `Create New` в правом верхнем углу, чтобы открыть форму создания приложения. Ниже перечислены поля и как их правильно заполнять:

* Название приложения: Может быть любым заметным именем, которое вы хотите использовать, чтобы легко распознавать ваше приложение среди других.
* Изображение: Может быть любым специфическим изображением, которое вы хотите использовать, чтобы легко распознавать ваше приложение среди других.
* Имя версии: Вы можете использовать имя версии, чтобы описать назначение версии, которую вы разворачиваете. Примеры: “demo”, “production”, “v1”, “v2”
* Контейнер:
  * Реестр: “ \[URL] ”, где \[URL] — это значение из учетных данных, которые вы можете показать на странице Container Repository.
  * Репозиторий изображения: “ \[PROJECT]/\[YOUR GAME] ”, где \[PROJECT] и \[YOUR GAME] — это значения, которые вы использовали ранее при отправке docker-образа.
  * Тэг: “ \[TAG] ”, где \[TAG] — это значение, которое вы использовали ранее при отправке docker-образа.
  * Отметьте “Using a private repository”
  * Имя пользователя приватного реестра: “ \[USERNAME] ”, где \[USERNAME] — это значение из ваших учетных данных.
  * Токен приватного реестра: “ \[TOKEN] ”, где \[TOKEN] — это значение из ваших учетных данных.
  * Требования: Оставить без изменений.
  * Порты: Нажмите на `+ Add port` ссылку, чтобы добавить новый порт, и добавьте следующие записи:
    * `7778` - WS - включить TLS Upgrade (Бета)

{% hint style="warning" %}
Если вы используете опцию WSS, важно включить опцию `TLS Upgrade` . В противном случае вы столкнетесь с ошибками, похожими на эту, в логах контейнера на панели Edgegap.

```cmd
Первые байты от клиента не были 'GET' для рукопожатия, вместо этого были 16-03-01
```

{% endhint %}

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

После создания приложения вы можете нажать кнопку `Deploy` чтобы приступить к деплою вашего серверa игры. Как только последний статус деплоя станет `Ready`, вы сможете подключиться к серверу с клиентской версией игры. Обратите внимание на `Host` URL и, на вкладке Port Mapping вашего деплоя, на `внешний порт` , доступный публично.

### Тестирование клиента

#### В редакторе

Возвратясь в редактор Unity в сцене с танком, выберите `NetworkManager` gameObject и измените следующие настройки:

* В `Компонент` Network Manager
  * : `Установите` Network Address `Host` в адрес деплоя сервера;
  * Снимите галочку с `Auto Start Server Build` .
* В `Simple Web Transport` Network Manager
  * : `Поле Port` значение на порт Edgegap деплоя, `внешний порт` например: `32821`;
  * Убедитесь, что опция `Client Use WSS` включена.

<figure><img src="/files/9ccc4b566a90154ce92697ce297b9f238a70b205" alt=""><figcaption></figcaption></figure>

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

После этого нажмите `Play` в редакторе, затем нажмите кнопку `Client` ; Вы подключитесь к серверу и сможете сыграть через короткое время.

#### На Itch.io

Чтобы разместить клиент игры на Itch, вам нужно выполнить сборку клиента; для этого необходимо установить модуль `WebGL Build Support` для вашей версии Unity. После этого вернитесь в `Экран сборки` редактора Unity, в меню `File -> Build Settings`и выберите следующие опции:

* Установите `Platform` в `WebGL`;
* Откройте `Player Settings`. В разделе `Player -> Publishing Settings`установите `Compression Format` в `Gzip` и убедитесь, что опция `Decompression Fallback` выбрана. Сохраните эти настройки и закройте окно.

<figure><img src="/files/7f7da874c07ab3bf673a3c50d3f182857f2cf289" alt=""><figcaption></figcaption></figure>

Затем нажмите собрать и выберите новую пустую папку с именем `сборка` в качестве места назначения файлов. Перенесите папку `сборка` в другую пустую папку, которая в этом документе будет называться `[CLIENT BUILD]` папка в этом документе.

После завершения сборки игры сожмите файлы этой `сборка` папки в zip-архив, убедившись, что они находятся в корне архива. Затем просто загрузите zip-архив в ваш проект на Itch и убедитесь, что выбрана опция воспроизведения файла в браузере. После запуска игры убедитесь, что значения сетевого адреса и порта правильно установлены в HUD, затем нажмите кнопку `Client` чтобы играть.

#### Хостинг клиента на Edgegap

Также можно разместить клиент вашей игры на Edgegap! Для этого добавьте следующий `Dockerfile` и `nginx.conf` файлы в эту `[CLIENT BUILD]` папку:

**Dockerfile**

```
FROM nginx:alpine
MAINTAINER <author_detail>

COPY build/ /usr/share/nginx/html
copy nginx.conf /etc/nginx/
```

**nginx.conf**

```
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 сервера
# ...

    # Файлы данных, предварительно сжатые Brotli на диске, должны обслуживаться с включённой компрессией:
    location ~ .+\.(data|symbols\.json)\.br$ {
        # Поскольку этот файл уже предварительно сжат на диске, отключите для него динамическое сжатие.
        # Иначе nginx попытается выполнить двойное сжатие.
        gzip off;
        add_header Content-Encoding br;
        default_type application/octet-stream;
    }

    # Файлы JavaScript, предварительно сжатые Brotli на диске:
    location ~ .+\.js\.br$ {
        gzip off; # Не пытайтесь динамически gzip-сжимать уже сжатый файл
        add_header Content-Encoding br;
        default_type application/javascript;
    }

    # Файлы WebAssembly, предварительно сжатые Brotli на диске:
    location ~ .+\.wasm\.br$ {
        gzip off; # Не пытайтесь динамически gzip-сжимать уже сжатый файл
        add_header Content-Encoding br;
        # Включите потоковую компиляцию WebAssembly, указав корректный MIME-тип для
        # Wasm-файлов.
        default_type application/wasm;
    }

    # Файлы данных, предварительно сжатые gzip на диске, должны обслуживаться с включённой компрессией:
    location ~ .+\.(data|symbols\.json)\.gz$ {
        gzip off; # Не пытайтесь динамически gzip-сжимать уже сжатый файл
        add_header Content-Encoding gzip;
        default_type application/octet-stream;
    }

    # Файлы JavaScript, предварительно сжатые gzip на диске:
    location ~ .+\.js\.gz$ {
        gzip off; # Не пытайтесь динамически gzip-сжимать уже сжатый файл
        add_header Content-Encoding gzip;
        default_type application/javascript;
    }

    # Файлы WebAssembly, предварительно сжатые gzip на диске:
    location ~ .+\.wasm\.gz$ {
        gzip off; # Не пытайтесь динамически gzip-сжимать уже сжатый файл
        add_header Content-Encoding gzip;
        # Включите потоковую компиляцию WebAssembly, указав корректный MIME-тип для
        # Wasm-файлов.
        default_type application/wasm;
    }
}
}
```

Продолжите с [тем же набором команд Docker, что и ранее](#bootsh) чтобы собрать и отправить образ вашего игрового клиента в приватный репозиторий, но из окна командной строки, открытого в `[CLIENT BUILD]` папке. Убедитесь, что используется другое имя образа, чем для вашего сервера.

Затем создайте новое приложение для вашего клиента на панели управления Edgegap со следующими настройками:

* Название приложения: Может быть любым заметным именем, которое вы хотите использовать, чтобы легко распознавать ваше приложение среди других.
* Изображение: Может быть любым специфическим изображением, которое вы хотите использовать, чтобы легко распознавать ваше приложение среди других.
* Имя версии: Вы можете использовать имя версии, чтобы описать назначение версии, которую вы разворачиваете. Примеры: “demo”, “production”, “v1”, “v2”
* Контейнер:
  * Реестр: “ \[URL] ”, где \[URL] — это значение из учетных данных, которые вы можете показать на странице Container Repository.
  * Репозиторий изображения: “ \[PROJECT]/\[YOUR GAME] ”, где \[PROJECT] и \[YOUR GAME] — это значения, которые вы использовали ранее при отправке docker-образа.
  * Тэг: “ \[TAG] ”, где \[TAG] — это значение, которое вы использовали ранее при отправке docker-образа.
  * Отметьте “Using a private repository”
  * Имя пользователя приватного реестра: “ \[USERNAME] ”, где \[USERNAME] — это значение из ваших учетных данных.
  * Токен приватного реестра: “ \[TOKEN] ”, где \[TOKEN] — это значение из ваших учетных данных.
  * Требования: Оставить без изменений.
  * Порты: Нажмите на `+ Add port` ссылку, чтобы добавить новый порт, и добавьте следующие записи:
    * `80` - HTTPS

<figure><img src="/files/5502efbb041266ea64c55874a9f662f7aafdf34a" alt=""><figcaption></figcaption></figure>

После создания приложения вы можете нажать кнопку `Deploy` кнопкой для продолжения развертывания вашего игрового клиента. При условии, что развертывания сервера и клиента установлены на `Ready`, откройте у игрового клиента `Host` url по указанному `внешний порт` в вашем браузере, и вы сможете играть в игру после установки правильных значений в HUD игры!

<figure><img src="/files/e16c8a66330822b2bcac82ae788e883666164fff" 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/ru/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.
