# 미러 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) 에서 사용하여 프로세스를 자동화할 수 있습니다. 이 플러그인 사용 방법에 대한 자세한 내용은 [문서](broken://pages/749f54d5ea9e89689928f4eb24c21ad8c20d25df).

를 확인하세요. 대신 원하시면 다음 단계별 지침을 따를 수도 있습니다.
{% 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="/files/bce372766dc2c0357e73d8ef2c025a5329e63d7e" 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="/files/5c1223bcdeea5d3a37360dd3fdb5747183d8745c" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/67ea5dd5ceb924bc69204e3d7c275439909a08b6" 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="/files/0023f159a64d716f09da5ce89bd13b064bc7341f" 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="/files/c0e74b58ec64018e0ec98d241ecc10440bf6765e" alt=""><figcaption></figcaption></figure>

애플리케이션이 생성되면 `Deploy` 버튼을 눌러 게임 클라이언트 배포를 진행하세요. 서버와 클라이언트 배포가 모두 `Ready`로 설정되면, 게임 클라이언트의 `Host` 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 %}


---

# 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/docs.edgegap.com-ko/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.
