# Mirror WebGL

이 가이드는 다음을 사용하는 방법을 안내합니다 [Mirror](https://mirror-networking.com/)의 Websocket 전송(Transport)을 사용하고 Unity 프로젝트용으로 Edgegap에 헤드리스 서버를 생성하는 방법을 안내합니다.

이 가이드에서는 오픈 소스 샘플 프로젝트를 사용합니다 `Tanks`는 Mirror 샘플의 다음 위치에서 사용할 수 있습니다 `Assets/Mirror/Examples/Tanks`.

이 샘플의 최종 버전은 우리의 [GitHub](https://github.com/edgegap/mirror-webgl)

### 전송(transport) 변경

게임 서버를 빌드할 준비가 되기 전에 기본 씬에 몇 가지 변경을 해야 합니다.

* 다음 파일을 엽니다 `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]라 칭함)를 메모해 두세요. `[GAME PORT]`이 경우 사용된 포트는 `7778`.

### 게임 서버 빌드 및 컨테이너화

{% hint style="info" %}
컨테이너화 및 배포 과정을 용이하게 하기 위해 Edgegap Unity Plugin의 최신 버전을 우리의 [GitHub](https://github.com/edgegap/edgegap-unity-plugin) 에서 사용하여 프로세스를 자동화할 수 있습니다. 이 플러그인 사용 방법에 대한 자세한 내용은 [문서](https://docs.edgegap.com/docs.edgegap.com-ko/docs/sample-projects/unity-netcodes/broken-reference).

를 확인하세요. 대신 원하시면 다음 단계별 지침을 따를 수도 있습니다.
{% endhint %}

게임 준비가 완료되면, `빌드(Build)` 화면으로 이동하세요, 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
# 이미지 빌드
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>
```

#### cmd 사용 시

```bash
# 이미지 빌드
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>
```

#### Powershell 사용 시

```bash
# 이미지 빌드
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>
```

### 서버를 Edgegap에 배포하기

Edgegap 대시보드에 로그인한 후, `Applications & Games` 페이지로 이동하세요. 우측 상단의 `Create New` 버튼을 클릭하여 애플리케이션 폼에 접근하세요. 다음은 각 필드와 올바르게 입력하는 방법입니다:

* 애플리케이션 이름: 다른 애플리케이션들 사이에서 쉽게 알아볼 수 있도록 원하는 임의의 이름을 사용할 수 있습니다.
* 이미지: 애플리케이션을 쉽게 식별하기 위해 사용하고 싶은 특정 이미지를 지정할 수 있습니다.
* 버전 이름: 배포 중인 버전의 범위를 설명하기 위한 버전 이름을 사용할 수 있습니다. 예: “demo”, “production”, “v1”, “v2”
* 컨테이너:
  * 레지스트리: “\[URL]”, 여기서 \[URL]은 Container Repository 페이지에서 표시할 수 있는 자격증명 값입니다.
  * 이미지 저장소: “\[PROJECT]/\[YOUR GAME]”, 여기서 \[PROJECT]와 \[YOUR GAME]은 도커 이미지를 푸시할 때 사용한 값입니다.
  * 태그: “\[TAG]”, 여기서 \[TAG]는 도커 이미지를 푸시할 때 사용한 값입니다.
  * “Using a private repository” 옵션에 체크하세요
  * 프라이빗 레지스트리 사용자 이름: “\[USERNAME]”, 여기서 \[USERNAME]은 자격증명에서 가져온 값입니다.
  * 프라이빗 레지스트리 토큰: “\[TOKEN]”, 여기서 \[TOKEN]은 자격증명에서 가져온 값입니다.
  * 요구사항: 기본값 그대로 두세요.
  * 포트: 새 포트를 추가하려면 `+ Add port` 링크를 클릭하고 다음 항목들을 추가하세요:
    * `7778` - WS - TLS 업그레이드 활성화 (베타)

{% hint style="warning" %}
WSS 옵션을 사용하는 경우, `TLS Upgrade` 옵션을 활성화하는 것이 중요합니다. 그렇지 않으면 Edgegap 대시보드의 컨테이너 로그에서 다음과 유사한 오류를 만나게 될 수 있습니다.

```cmd
클라이언트의 첫 바이트가 핸드셰이크용 'GET'이 아니었고 대신 16-03-01이었습니다
```

{% endhint %}

<figure><img src="https://1562312210-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FsR0dHSFv9ymoC0DO5G8J%2Fuploads%2Fgit-blob-4996c904d603b04628fdd82091b1d3a5768aac40%2Fserver-port.png?alt=media" alt=""><figcaption></figcaption></figure>

애플리케이션이 생성되면 `Deploy` 버튼을 눌러 게임 서버 배포를 진행하세요. 배포의 최신 상태가 `Ready`로 설정되면, 게임 클라이언트 버전으로 서버에 접속할 수 있습니다. 다음을 메모하세요: `Host` URL과 배포의 Port Mapping 탭에서 공개적으로 사용 가능한 `외부 포트` .

### 클라이언트 테스트

#### 에디터에서

Unity 에디터의 탱크 씬으로 돌아가서, `NetworkManager` 게임 오브젝트를 선택하고 다음 설정을 변경하세요:

* 에서 `Network Manager` 구성 요소:
  * 다음 항목을 설정하세요 `Network Address` 를 서버 배포의 `Host` URL로;
  * 다음 항목의 선택을 해제하세요 `Auto Start Server Build` Server Build
* 에서 `Simple Web Transport` 구성 요소:
  * 다음 항목을 설정하세요 `포트` 값을 Edgegap 배포의 `외부 포트` 예:  `32821`;
  * 다음 옵션(Client Use WSS)이 활성화되어 있는지 확인하세요. `Client Use WSS` 옵션이 활성화되어 있는지 확인하세요.

<figure><img src="https://1562312210-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FsR0dHSFv9ymoC0DO5G8J%2Fuploads%2Fgit-blob-8fe3a5d63fc65f33f18d8e0c39a5d2d5a5b97e6c%2Fnetwork-manager-client-settings-1.png?alt=media" alt=""><figcaption></figcaption></figure>

<figure><img src="https://1562312210-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FsR0dHSFv9ymoC0DO5G8J%2Fuploads%2Fgit-blob-8a7da870b869174fc4117dc6e6e44edb8e62b906%2Fnetwork-manager-client-settings-2.png?alt=media" alt=""><figcaption></figcaption></figure>

설정이 완료되면, 에디터에서 `Play` 를 클릭한 다음, `Client` 버튼을 클릭하세요; 잠시 후 서버에 연결되어 게임을 플레이할 수 있게 됩니다.

#### Itch.io에서

Itch에 게임 클라이언트를 올리려면 클라이언트 빌드를 만들어야 합니다; 이를 위해서는 해당 Unity 버전용 `WebGL Build Support` 모듈을 설치해야 합니다. 설치가 완료되면 다시 `빌드(Build)` 화면으로 이동하세요, Unity 에디터의 `File -> Build Settings`로 돌아가 다음 옵션을 선택하세요:

* 다음으로 설정 `Platform` 을 `WebGL`;
* Player Settings `를 엽니다`. 아래의 `Player -> Publishing Settings`에서, `압축 형식(Compression Format)` 을 `을` Gzip `으로 설정하고` Decompression Fallback

<figure><img src="https://1562312210-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FsR0dHSFv9ymoC0DO5G8J%2Fuploads%2Fgit-blob-04b0077a769072f95884b660b71bc3e93655f6a6%2Fclient-build.png?alt=media" alt=""><figcaption></figcaption></figure>

그런 다음 빌드를 누르고 파일 대상 폴더로 새 빈 폴더를 선택하세요 `옵션이 선택되어 있는지 확인하세요. 이 설정을 저장하고 창을 닫으세요.` 로. 생성된 `옵션이 선택되어 있는지 확인하세요. 이 설정을 저장하고 창을 닫으세요.` 폴더를 두 번째 빈 폴더로 복사하세요. 이 문서에서는 해당 폴더를 `빌드` \[CLIENT BUILD]

폴더(문서 내 지정된). `옵션이 선택되어 있는지 확인하세요. 이 설정을 저장하고 창을 닫으세요.` 게임 빌드가 완료되면 이 `Client` 폴더의 파일들을 루트에 오도록 압축(zip)하세요. 그런 다음 해당 zip 파일을 Itch 프로젝트에 업로드하고, 파일이 브라우저에서 재생되도록 하는 옵션을 선택하세요. 게임을 실행하면 HUD에서 네트워크 주소와 포트 값이 올바르게 설정되어 있는지 확인한 후

#### 버튼을 클릭하여 재생하세요.

클라이언트를 Edgegap에 호스팅하기 `Dockerfile` 과 `게임 클라이언트를 Edgegap에 호스팅하는 것도 가능합니다! 이를 위해 다음` 파일을 `빌드` 폴더에 추가하세요:

**Dockerfile**

```
nginx.conf
MAINTAINER <author_detail>

를 추가하세요
FROM nginx:alpine
```

**게임 클라이언트를 Edgegap에 호스팅하는 것도 가능합니다! 이를 위해 다음**

```
COPY build/ /usr/share/nginx/html
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 서버 구성 내에 다음 구성을 추가하세요
        # 디스크에 Brotli로 미리 압축된 데이터 파일은 압축이 활성화된 상태로 제공되어야 합니다:
        location ~ .+\.(data|symbols\.json)\.br$ {
        # 이 파일은 이미 디스크에 미리 압축되어 있으므로, 파일에 대해 온디맨드 압축을 비활성화하세요.
        # 그렇지 않으면 nginx가 이중 압축을 시도할 것입니다.
        gzip off;
    }

    add_header Content-Encoding br;
    default_type application/octet-stream;
        # 디스크에 미리 Brotli로 압축된 자바스크립트 파일:
        # 그렇지 않으면 nginx가 이중 압축을 시도할 것입니다.
        location ~ .+\.js\.br$ {
    }

    gzip off; # 이미 압축된 파일에 동적 gzip 압축을 시도하지 마세요
    default_type application/javascript;
        # 디스크에 미리 Brotli로 압축된 자바스크립트 파일:
        # 그렇지 않으면 nginx가 이중 압축을 시도할 것입니다.
        # 디스크에 미리 Brotli로 압축된 WebAssembly 파일:
        location ~ .+\.wasm\.br$ {
        # Wasm 파일에 대해 올바른 MIME 타입을 지정하여 스트리밍 WebAssembly 컴파일을 활성화하세요.
    }

    default_type application/wasm;
    # 디스크에 미리 gzip으로 압축된 데이터 파일은 압축이 활성화된 상태로 제공되어야 합니다:
        # 디스크에 미리 Brotli로 압축된 자바스크립트 파일:
        location ~ .+\.(data|symbols\.json)\.gz$ {
        gzip off;
    }

    add_header Content-Encoding gzip;
    # 디스크에 미리 gzip으로 압축된 자바스크립트 파일:
        # 디스크에 미리 Brotli로 압축된 자바스크립트 파일:
        location ~ .+\.(data|symbols\.json)\.gz$ {
        location ~ .+\.js\.br$ {
    }

    location ~ .+\.js\.gz$ {
    # 디스크에 미리 gzip으로 압축된 WebAssembly 파일:
        # 디스크에 미리 Brotli로 압축된 자바스크립트 파일:
        location ~ .+\.(data|symbols\.json)\.gz$ {
        # 디스크에 미리 Brotli로 압축된 WebAssembly 파일:
        location ~ .+\.wasm\.br$ {
        # Wasm 파일에 대해 올바른 MIME 타입을 지정하여 스트리밍 WebAssembly 컴파일을 활성화하세요.
    }
}
}
```

location \~ .+\\.wasm\\.gz$ { [이전과 동일한 Docker 명령을 진행하여](#bootsh) 게임 클라이언트의 이미지를 빌드하고 프라이빗 저장소로 푸시하되, 명령 창은 `빌드` 폴더에서 열어 진행하세요. 서버용 이미지와 다른 이미지 이름을 사용해야 합니다.

그런 다음, 다음 설정으로 Edgegap 대시보드에 클라이언트용 새 애플리케이션을 생성하세요:

* 애플리케이션 이름: 다른 애플리케이션들 사이에서 쉽게 알아볼 수 있도록 원하는 임의의 이름을 사용할 수 있습니다.
* 이미지: 애플리케이션을 쉽게 식별하기 위해 사용하고 싶은 특정 이미지를 지정할 수 있습니다.
* 버전 이름: 배포 중인 버전의 범위를 설명하기 위한 버전 이름을 사용할 수 있습니다. 예: “demo”, “production”, “v1”, “v2”
* 컨테이너:
  * 레지스트리: “\[URL]”, 여기서 \[URL]은 Container Repository 페이지에서 표시할 수 있는 자격증명 값입니다.
  * 이미지 저장소: “\[PROJECT]/\[YOUR GAME]”, 여기서 \[PROJECT]와 \[YOUR GAME]은 도커 이미지를 푸시할 때 사용한 값입니다.
  * 태그: “\[TAG]”, 여기서 \[TAG]는 도커 이미지를 푸시할 때 사용한 값입니다.
  * “Using a private repository” 옵션에 체크하세요
  * 프라이빗 레지스트리 사용자 이름: “\[USERNAME]”, 여기서 \[USERNAME]은 자격증명에서 가져온 값입니다.
  * 프라이빗 레지스트리 토큰: “\[TOKEN]”, 여기서 \[TOKEN]은 자격증명에서 가져온 값입니다.
  * 요구사항: 기본값 그대로 두세요.
  * 포트: 새 포트를 추가하려면 `+ Add port` 링크를 클릭하고 다음 항목들을 추가하세요:
    * `80` - HTTPS

<figure><img src="https://1562312210-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FsR0dHSFv9ymoC0DO5G8J%2Fuploads%2Fgit-blob-f88e313ed093082a221680f4b59b241afe7cbf70%2Fclient-port.png?alt=media" alt=""><figcaption></figcaption></figure>

애플리케이션이 생성되면 `Deploy` 버튼을 눌러 게임 클라이언트 배포를 진행하세요. 서버와 클라이언트 배포가 모두 `Ready`로 설정되면, 게임 클라이언트의 `Host` URL을 지정된 `외부 포트` 에서 브라우저로 열면, 게임의 HUD에서 올바른 값을 설정한 후 게임을 플레이할 수 있습니다!

<figure><img src="https://1562312210-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FsR0dHSFv9ymoC0DO5G8J%2Fuploads%2Fgit-blob-b140451a9c9404cba2498e715c6c83abb656e655%2Fonline-client.png?alt=media" alt=""><figcaption></figcaption></figure>

{% hint style="info" %}
Mirror 통합 및 웹소켓에 대한 추가 정보가 필요하면, 그들의 [문서](https://mirror-networking.gitbook.io/docs/manual/transports/websockets-transport).
{% endhint %}
