# Mirror WebGL

Ce guide vous aidera à utiliser [Mirror](https://mirror-networking.com/)le transport Websocket et à créer un serveur sans interface sur Edgegap pour un projet Unity.

Ce guide utilisera le projet d'exemple open-source `Tanks`disponible dans l'exemple Mirror sous `Assets/Mirror/Examples/Tanks`.

Vous pouvez trouver la version finale de cet exemple sur notre [GitHub](https://github.com/edgegap/mirror-webgl)

### Changer le transport

Nous devons d'abord effectuer quelques modifications sur la scène de base avant d'être prêts à construire le serveur du jeu.

* Ouvrez `Scene.unity` situé sous `Assets/Mirror/Examples/Tanks/Scenes`;
* Dans le `NetworkManager` gameObject, supprimez le `KcpTransport` script et remplacez-le par le `SimpleWebTransport` situé sous `Assets/Mirror/Transports/SimpleWeb`, assurez-vous également de mettre à jour le champ Transport du `NetworkManager` composant script avec ce nouveau transport. Assurez-vous également que l'option `Auto Start Server Build` est sélectionnée.
* Selon votre version de Mirror, vous pourriez avoir besoin de changer/mette à jour le `NetworkManagerHUD` pour le faire fonctionner avec des transports différents de KCP, ainsi que pour vous permettre de saisir la valeur du port dans le HUD avant de rejoindre un serveur.

Prenez note du port utilisé pour les communications réseau, appelé `[GAME PORT]`. Dans ce cas, le port utilisé est `7778`.

### Construire le serveur de jeu & Conteneurisation

{% hint style="info" %}
Pour faciliter le processus de conteneurisation et de déploiement, il est possible d'utiliser la dernière version du plugin Unity Edgegap sur notre [GitHub](https://github.com/edgegap/edgegap-unity-plugin) pour automatiser le processus. Pour plus d'informations sur l'utilisation de ce plugin, vous pouvez consulter notre [documentation](https://docs.edgegap.com/docs.edgegap.com-fr/docs/sample-projects/unity-netcodes/broken-reference).

Si vous préférez, vous pouvez également suivre ces instructions étape par étape.
{% endhint %}

Une fois que votre jeu est prêt, rendez-vous sur la `Build` écran de l'éditeur Unity, sous `File -> Build Settings` dans les menus en haut. Assurez-vous de sélectionner les bons préréglages en fonction de votre version d'Unity.

* Avant la version 2021.2 :
  * Définissez `Target Platform` sur `Linux`;
  * Définissez `Architecture` sur `x86_64`;
  * Cochez l'option `Server Build` .
* Sinon :
  * Définissez `Platform` sur `Dedicated Server`;
  * Définissez `Target Platform` sur `Linux`.

Puis appuyez sur build et sélectionnez un nouveau dossier vide nommé `linux_server` comme destination du fichier. Transférez le `linux_server` dossier vers un deuxième dossier vide, qui sera appelé `[SERVER BUILD]` dans ce document. Ajoutez les fichiers suivants `Dockerfile` et `boot.sh` au dossier `[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
```

Assurez-vous de remplacer les `[YOUR GAME]` espaces réservés par le nom du fichier généré

Ensuite, ouvrez une invite de commande dans le `[SERVER BUILD]` dossier ; Exécutez les commandes Docker suivantes pour créer une image de votre build et la pousser vers un registre privé :

{% hint style="warning" %}
Pour les utilisateurs de CPU ARM (Mac M1, M2, etc.), ajoutez `--platform linux/amd64`  option à votre commande de build.
{% endhint %}

#### Utilisation de 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>
```

#### Utilisation de 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>
```

#### Utilisation de 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>
```

### Déployer le serveur sur Edgegap

Après s'être connecté au tableau de bord Edgegap, naviguez vers la page `Applications & Games` Cliquez sur le `Create New` bouton en haut à droite pour accéder au formulaire d'application. Voici les champs et comment les remplir correctement :

* Nom de l'application : Peut être n'importe quel nom notable que vous souhaitez utiliser pour reconnaître facilement votre application parmi d'autres.
* Image : Peut être n'importe quelle image spécifique que vous souhaitez utiliser pour reconnaître facilement votre application parmi d'autres.
* Nom de version : Vous pouvez utiliser un nom de version pour décrire la portée de la version que vous déployez. Des exemples peuvent être « demo », « production », « v1 », « v2 »
* Conteneur :
  * Registry : « \[URL] », où \[URL] est la valeur des identifiants que vous pouvez afficher sur la page du dépôt de conteneurs.
  * Image repository : « \[PROJECT]/\[YOUR GAME] », où \[PROJECT] et \[YOUR GAME] sont les valeurs que vous avez utilisées précédemment lors de la poussée de l'image docker.
  * Tag : « \[TAG] », où \[TAG] est la valeur que vous avez utilisée précédemment lors de la poussée de l'image docker.
  * Cochez « Using a private repository »
  * Nom d'utilisateur du registre privé : « \[USERNAME] », où \[USERNAME] est la valeur de vos identifiants.
  * Jeton du registre privé : « \[TOKEN] », où \[TOKEN] est la valeur de vos identifiants.
  * Exigences : Laisser tel quel.
  * Ports : Cliquez sur le `+ Add port` lien pour ajouter un nouveau port, et ajoutez les entrées suivantes :
    * `7778` - WS - enable TLS Upgrade (Beta)

{% hint style="warning" %}
Si vous utilisez l'option WSS, il est important d'activer l'option `TLS Upgrade` Sinon, vous rencontrerez des erreurs similaires à celle-ci dans les journaux de votre conteneur sur le tableau de bord Edgegap.

```cmd
First bytes from client was not 'GET' for handshake, instead was 16-03-01
```

{% endhint %}

<figure><img src="https://3008966946-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>

Une fois que votre application a été créée, vous pouvez appuyer sur le `Deploy` bouton pour poursuivre le déploiement de votre serveur de jeu. Une fois que le dernier statut de votre déploiement est défini sur `Ready`, vous pourrez vous connecter au serveur avec une version cliente du jeu. Prenez note de l' `Host` url et, dans l'onglet Port Mapping de votre déploiement, du `port externe` qui est disponible publiquement.

### Tester le client

#### Dans l'éditeur

De retour dans l'éditeur Unity, dans la scène des tanks, sélectionnez le `NetworkManager` gameObject et modifiez les paramètres suivants :

* Dans le `Network Manager` composant :
  * Définissez le `Network Address` sur l' `Host` url ;
  * Décochez le `Auto Start Server Build` .
* Dans le `Simple Web Transport` composant :
  * Définissez le `Port` valeur sur le `port externe` deploiement Edgegap par exemple : `32821`;
  * Assurez-vous que l'option `Client Use WSS` est activée.

<figure><img src="https://3008966946-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://3008966946-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>

Une fois cela fait, cliquez sur `Play` dans l'éditeur, puis cliquez sur le bouton `Client` ; Vous serez connecté au serveur et pourrez jouer au jeu après un court instant.

#### Sur Itch.io

Pour mettre votre client de jeu sur Itch, vous devrez faire une compilation client ; Vous devrez installer le module `WebGL Build Support` pour votre version d'Unity pour cela. Une fois cela fait, revenez au `Build` écran de l'éditeur Unity, sous `File -> Build Settings`et sélectionnez les options suivantes :

* Définissez `Platform` sur `WebGL`;
* Ouvrez les `Player Settings`. Sous `Player -> Publishing Settings`, définissez le `Compression Format` sur `Gzip` et assurez-vous que l'option `Decompression Fallback` est sélectionnée. Enregistrez ces paramètres, puis fermez la fenêtre.

<figure><img src="https://3008966946-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>

Puis appuyez sur build et sélectionnez un nouveau dossier vide nommé `build` comme destination du fichier. Transférez le `build` dossier vers un deuxième dossier vide, qui sera appelé `[CLIENT BUILD]` dossier dans ce document.

Une fois que votre jeu a terminé la compilation, compressez les fichiers de ce `build` dossier dans un dossier zip, en vous assurant qu'ils se trouvent à la racine de celui-ci. Ensuite, il vous suffit de télécharger le dossier zip sur votre projet Itch et de vous assurer de sélectionner l'option pour que le fichier puisse être lu dans le navigateur. Une fois que vous lancez le jeu, vous devez simplement vous assurer que les valeurs d'adresse réseau et de port sont correctement définies dans le HUD, puis cliquer sur le `Client` bouton pour jouer.

#### Héberger le client sur Edgegap

Il est même possible d'héberger votre client de jeu sur Edgegap ! Pour ce faire, ajoutez le fichier suivant `Dockerfile` et `nginx.conf` au dossier `[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 {
# Ajoutez la configuration suivante dans la configuration du serveur http
# ...

    # Les fichiers de données précompressés Brotli sur disque doivent être servis avec la compression activée :
    location ~ .+\.(data|symbols\.json)\.br$ {
        # Parce que ce fichier est déjà précompressé sur le disque, désactivez la compression à la demande pour celui-ci.
        # Sinon nginx tenterait une double compression.
        gzip off;
        add_header Content-Encoding br;
        default_type application/octet-stream;
    }

    # Fichiers JavaScript précompressés Brotli sur disque :
    location ~ .+\.js\.br$ {
        gzip off; # Ne pas tenter de compression gzip dynamique sur un fichier déjà compressé
        add_header Content-Encoding br;
        default_type application/javascript;
    }

    # Fichiers WebAssembly précompressés Brotli sur disque :
    location ~ .+\.wasm\.br$ {
        gzip off; # Ne pas tenter de compression gzip dynamique sur un fichier déjà compressé
        add_header Content-Encoding br;
        # Activez la compilation WebAssembly en streaming en spécifiant le bon type MIME pour
        # les fichiers Wasm.
        default_type application/wasm;
    }

    # Les fichiers de données précompressés gzip sur disque doivent être servis avec la compression activée :
    location ~ .+\.(data|symbols\.json)\.gz$ {
        gzip off; # Ne pas tenter de compression gzip dynamique sur un fichier déjà compressé
        add_header Content-Encoding gzip;
        default_type application/octet-stream;
    }

    # Fichiers JavaScript précompressés gzip sur disque :
    location ~ .+\.js\.gz$ {
        gzip off; # Ne pas tenter de compression gzip dynamique sur un fichier déjà compressé
        add_header Content-Encoding gzip;
        default_type application/javascript;
    }

    # Fichiers WebAssembly précompressés gzip sur disque :
    location ~ .+\.wasm\.gz$ {
        gzip off; # Ne pas tenter de compression gzip dynamique sur un fichier déjà compressé
        add_header Content-Encoding gzip;
        # Activez la compilation WebAssembly en streaming en spécifiant le bon type MIME pour
        # les fichiers Wasm.
        default_type application/wasm;
    }
}
}
```

Procédez avec les [mêmes commandes Docker qu'auparavant](#bootsh) pour construire et pousser une image de votre client de jeu vers un dépôt privé, mais depuis une fenêtre de commande ouverte dans le dossier `[CLIENT BUILD]` . Assurez-vous d'utiliser un nom d'image différent de celui de votre serveur.

Ensuite, créez une nouvelle application pour votre client sur le tableau de bord Edgegap avec les paramètres suivants :

* Nom de l'application : Peut être n'importe quel nom notable que vous souhaitez utiliser pour reconnaître facilement votre application parmi d'autres.
* Image : Peut être n'importe quelle image spécifique que vous souhaitez utiliser pour reconnaître facilement votre application parmi d'autres.
* Nom de version : Vous pouvez utiliser un nom de version pour décrire la portée de la version que vous déployez. Des exemples peuvent être « demo », « production », « v1 », « v2 »
* Conteneur :
  * Registry : « \[URL] », où \[URL] est la valeur des identifiants que vous pouvez afficher sur la page du dépôt de conteneurs.
  * Image repository : « \[PROJECT]/\[YOUR GAME] », où \[PROJECT] et \[YOUR GAME] sont les valeurs que vous avez utilisées précédemment lors de la poussée de l'image docker.
  * Tag : « \[TAG] », où \[TAG] est la valeur que vous avez utilisée précédemment lors de la poussée de l'image docker.
  * Cochez « Using a private repository »
  * Nom d'utilisateur du registre privé : « \[USERNAME] », où \[USERNAME] est la valeur de vos identifiants.
  * Jeton du registre privé : « \[TOKEN] », où \[TOKEN] est la valeur de vos identifiants.
  * Exigences : Laisser tel quel.
  * Ports : Cliquez sur le `+ Add port` lien pour ajouter un nouveau port, et ajoutez les entrées suivantes :
    * `80` - HTTPS

<figure><img src="https://3008966946-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>

Une fois que votre application a été créée, vous pouvez appuyer sur le `Deploy` bouton pour procéder au déploiement de votre client de jeu. Avec les déploiements du serveur et du client définis sur `Ready`, ouvrez l' `Host` url du client de jeu à la `port externe` spécifiée dans votre navigateur, et vous pourrez jouer au jeu après avoir défini les bonnes valeurs dans le HUD du jeu !

<figure><img src="https://3008966946-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" %}
Si vous avez besoin de plus d'informations sur l'intégration de Mirror et websocket, vous pouvez vous référer à leur [documentation](https://mirror-networking.gitbook.io/docs/manual/transports/websockets-transport).
{% endhint %}
