> For the complete documentation index, see [llms.txt](https://docs.edgegap.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.edgegap.com/ko/docs/sample-projects/unity-netcodes/mirror-on-edgegap-websocket.md).

# 미러 WebGL

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

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

이 샘플의 최종 버전은 우리의 [GitHub에서 찾을 수 있습니다](https://github.com/edgegap/mirror-webgl)

### Billiards 샘플

Billiard 샘플을 사용한 단계별 비디오 튜토리얼을 따르고 싶다면, 여기에서 보세요:

{% embed url="<https://youtu.be/zWs75VBfgD4>" %}

{% hint style="success" %}
이 비디오는 최신 [Unity](/ko/unity.md) 빌드 도구를 활용한 업데이트된 빌드 프로세스를 보여줍니다.
{% endhint %}

### 트랜스포트를 변경하세요

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

* 다음을 엽니다 `Scene.unity` 다음 위치에 있는 `Assets/Mirror/Examples/Tanks/Scenes`;
* 에서 `NetworkManager` 게임 오브젝트에서 다음을 제거하고 `KcpTransport` 스크립트를 다음으로 교체합니다 `SimpleWebTransport` 다음 위치에 있는 `Assets/Mirror/Transports/SimpleWeb`또한 `NetworkManager` 스크립트 컴포넌트의 Transport 필드도 이 새 트랜스포트로 업데이트해야 합니다. 또한 `서버 빌드 자동 시작` 옵션도 선택되어 있는지 확인하세요.
* Mirror 버전에 따라 KCP 이외의 트랜스포트에서도 작동하도록 하려면 `NetworkManagerHUD` 를 변경/업데이트해야 할 수도 있으며, 서버에 접속하기 전에 HUD에서 포트 값을 입력할 수 있도록 해야 합니다.

네트워크 통신에 사용되는 포트, 즉 `[GAME PORT]`를 기록해 두세요. 이 경우 사용되는 포트는 `7778`.

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

{% hint style="info" %}
컨테이너화 및 배포 과정을 쉽게 하기 위해, 최신 버전의 Edgegap Unity Plugin을 우리의 [GitHub에서 찾을 수 있습니다](https://github.com/edgegap/edgegap-unity-plugin) 프로세스를 자동화하는 데 사용할 수 있습니다. 이 플러그인의 사용 방법에 대한 자세한 정보는 우리의 [문서를 확인하세요](broken://pages/749f54d5ea9e89689928f4eb24c21ad8c20d25df).

원한다면, 아래의 단계별 안내를 따를 수도 있습니다.
{% endhint %}

게임이 준비되면 `빌드` 화면으로 이동한 뒤 `파일 -> 빌드 설정` 으로 들어가세요. Unity 버전에 따라 올바른 프리셋을 선택했는지 확인하세요.

* 2021.2 버전 이전에는:
  * 다음을 설정하세요 `대상 플랫폼` 를 `Linux`;
  * 다음을 설정하세요 `아키텍처` 를 `x86_64`;
  * 다음을 체크하세요 `서버 빌드` 옵션.
* 그 외에는:
  * 다음을 설정하세요 `플랫폼` 를 `전용 서버`;
  * 다음을 설정하세요 `대상 플랫폼` 를 `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 대시보드에 로그인한 후 `애플리케이션 및 게임` 페이지로 이동하세요. 다음을 클릭합니다 `새로 만들기` 오른쪽 상단 모서리의 버튼을 눌러 애플리케이션 양식을 엽니다. 다음은 각 필드와 올바르게 입력하는 방법입니다:

* 애플리케이션 이름 : 다른 것들 사이에서 애플리케이션을 쉽게 식별할 수 있도록 원하는 눈에 띄는 이름을 사용할 수 있습니다.
* 이미지 : 다른 것들 사이에서 애플리케이션을 쉽게 식별할 수 있도록 원하는 특정 이미지를 사용할 수 있습니다.
* 버전 이름 : 배포 중인 버전의 범위를 설명하기 위해 버전 이름을 사용할 수 있습니다. 예: “demo”, “production”, “v1”, “v2”
* 컨테이너 :
  * 레지스트리 : “\[URL]”, 여기서 \[URL]은 Container Repository 페이지에서 확인할 수 있는 자격 증명의 값입니다.
  * 이미지 저장소 : “\[PROJECT]/\[YOUR GAME]”, 여기서 \[PROJECT]와 \[YOUR GAME]은 이전에 Docker 이미지를 푸시할 때 사용한 값입니다.
  * 태그 : “\[TAG]”, 여기서 \[TAG]은 이전에 Docker 이미지를 푸시할 때 사용한 값입니다.
  * “비공개 저장소 사용”을 체크합니다
  * 비공개 레지스트리 사용자 이름 : “\[USERNAME]”, 여기서 \[USERNAME]은 자격 증명의 값입니다.
  * 비공개 레지스트리 토큰 : “\[TOKEN]”, 여기서 \[TOKEN]은 자격 증명의 값입니다.
  * 요구 사항 : 그대로 둡니다.
  * 포트 : 다음을 클릭합니다 `+ 포트 추가` 링크를 눌러 새 포트를 추가한 다음, 다음 항목을 입력하세요:
    * `7778` - WS - TLS 업그레이드 사용(베타)

{% hint style="warning" %}
WSS 옵션을 사용하는 경우 `TLS 업그레이드` 옵션을 활성화하는 것이 중요합니다. 그렇지 않으면 Edgegap 대시보드의 컨테이너 로그에서 이와 비슷한 오류를 만나게 됩니다.

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

{% endhint %}

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

애플리케이션이 생성되면 다음을 눌러 `배포` 게임 서버 배포를 진행할 수 있습니다. 배포의 최신 상태가 `Ready`로 설정되면 게임의 클라이언트 버전으로 서버에 연결할 수 있습니다. 다음을 기록해 두세요 `호스트` URL과, 배포의 Port Mapping 탭에서 `외부 포트` 를 확인할 수 있습니다.

### 클라이언트 테스트하기

#### 에디터에서

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

* 에서 `Network Manager` 컴포넌트:
  * 다음을 설정하세요 `Network Address` 를 서버 배포의 `호스트` URL로 설정하세요;
  * 다음의 선택을 해제합니다 `서버 빌드 자동 시작` 옵션.
* 에서 `Simple Web Transport` 컴포넌트:
  * 다음을 설정하세요 `포트` 값을 Edgegap 배포의 `외부 포트` 예: `32821`;
  * 다음이 `Client Use WSS` 옵션이 활성화되어 있는지 확인하세요.

<figure><img src="/files/5c1223bcdeea5d3a37360dd3fdb5747183d8745c" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/67ea5dd5ceb924bc69204e3d7c275439909a08b6" alt=""><figcaption></figcaption></figure>

이 작업이 끝나면 `플레이` 를 에디터에서 클릭한 다음 `클라이언트` 버튼을 클릭하세요. 잠시 후 서버에 연결되어 게임을 플레이할 수 있습니다.

#### Itch.io에서

게임 클라이언트를 Itch에 올리려면 클라이언트 빌드를 만들어야 합니다. 이를 위해서는 `WebGL Build Support` 모듈을 Unity 버전에 맞게 설치해야 합니다. 설치가 끝나면 다시 `빌드` 화면으로 이동한 뒤 `파일 -> 빌드 설정`로 돌아가 다음 옵션을 선택하세요:

* 다음을 설정하세요 `플랫폼` 를 `WebGL`;
* 다음을 엽니다 `Player Settings`. 아래에서 `Player -> Publishing Settings`, 다음으로 설정하세요: `압축 형식` 를 `Gzip` 그리고 다음이 `압축 해제 대체` 옵션이 선택되어 있는지 확인하세요. 이 설정을 저장하고 창을 닫습니다.

<figure><img src="/files/0023f159a64d716f09da5ce89bd13b064bc7341f" alt=""><figcaption></figcaption></figure>

그다음 빌드를 누르고 파일 대상 위치로 새 빈 폴더를 선택하세요 `빌드` 로 지정합니다. 다음을 `빌드` 폴더를 두 번째 빈 폴더로 옮기며, 이 폴더는 문서에서 다음으로 지칭됩니다 `[CLIENT BUILD]` 폴더입니다.

게임 빌드가 완료되면 이 `빌드` 폴더의 파일을 zip 폴더로 압축하되, 파일들이 zip의 루트에 있도록 하세요. 그런 다음 zip 폴더를 Itch 프로젝트에 업로드하고, 브라우저에서 파일을 재생하는 옵션을 선택하세요. 게임을 실행한 뒤에는 HUD에서 네트워크 주소와 포트 값이 올바르게 설정되었는지 확인한 다음 `클라이언트` 플레이 버튼을 누르세요.

#### 클라이언트를 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;
    }

    # 디스크에 있는 Brotli 사전 압축 JavaScript 코드 파일:
    location ~ .+\.js\.br$ {
        gzip off; # 이미 압축된 파일에 대해 동적 gzip 압축을 시도하지 마세요
        add_header Content-Encoding br;
        default_type application/javascript;
    }

    # 디스크에 있는 Brotli 사전 압축 WebAssembly 파일:
    location ~ .+\.wasm\.br$ {
        gzip off; # 이미 압축된 파일에 대해 동적 gzip 압축을 시도하지 마세요
        add_header Content-Encoding br;
        # Wasm 파일에 올바른 MIME 유형을 지정하여 스트리밍 WebAssembly 컴파일을 활성화합니다.
        # Wasm 파일입니다.
        default_type application/wasm;
    }

    # 디스크에 있는 gzip 사전 압축 데이터 파일은 압축을 활성화한 상태로 제공해야 합니다:
    location ~ .+\.(data|symbols\.json)\.gz$ {
        gzip off; # 이미 압축된 파일에 대해 동적 gzip 압축을 시도하지 마세요
        add_header Content-Encoding gzip;
        default_type application/octet-stream;
    }

    # 디스크에 있는 gzip 사전 압축 JavaScript 코드 파일:
    location ~ .+\.js\.gz$ {
        gzip off; # 이미 압축된 파일에 대해 동적 gzip 압축을 시도하지 마세요
        add_header Content-Encoding gzip;
        default_type application/javascript;
    }

    # 디스크에 있는 gzip 사전 압축 WebAssembly 파일:
    location ~ .+\.wasm\.gz$ {
        gzip off; # 이미 압축된 파일에 대해 동적 gzip 압축을 시도하지 마세요
        add_header Content-Encoding gzip;
        # Wasm 파일에 올바른 MIME 유형을 지정하여 스트리밍 WebAssembly 컴파일을 활성화합니다.
        # 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 이미지를 푸시할 때 사용한 값입니다.
  * “비공개 저장소 사용”을 체크합니다
  * 비공개 레지스트리 사용자 이름 : “\[USERNAME]”, 여기서 \[USERNAME]은 자격 증명의 값입니다.
  * 비공개 레지스트리 토큰 : “\[TOKEN]”, 여기서 \[TOKEN]은 자격 증명의 값입니다.
  * 요구 사항 : 그대로 둡니다.
  * 포트 : 다음을 클릭합니다 `+ 포트 추가` 링크를 눌러 새 포트를 추가한 다음, 다음 항목을 입력하세요:
    * `80` - HTTPS

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

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

<figure><img src="/files/87018cb1cbdd86b34cbd54616e12af5500e22096" alt=""><figcaption></figcaption></figure>

{% hint style="info" %}
Mirror 통합과 웹소켓에 대한 더 자세한 정보가 필요하다면, 해당 [문서를 확인하세요](https://mirror-networking.gitbook.io/docs/manual/transports/websockets-transport).
{% endhint %}
