# Server Browser

Ce SDK est un kit de démarrage optionnel pour les utilisateurs de Unity, qui peut être étendu et personnalisé ultérieurement.

## 💡 Fonctionnalités

Accédez à des fonctionnalités automatisées préconstruites en installant notre SDK :

{% columns %}
{% column %}

* Exemples complets
* Gestion du cycle de vie
* Gestion de la capacité
  {% endcolumn %}

{% column width="33.33333333333333%" %}

* Compilateur de requêtes de filtre
* Définitions de types (C#)
* Tests en développement local
  {% endcolumn %}

{% column width="33.33333333333333%" %}

* Multiplateforme
* Facile à personnaliser
* Nouvelle tentative automatique
  {% endcolumn %}
  {% endcolumns %}

## ✔️ Préparation

## 🍀 Premiers pas

Ce guide suppose une connaissance de base des [Server Browser](/docs.edgegap.com-fr/learn/server-browser.md) concepts et d’un Server Browser fonctionnel.

{% hint style="success" %}
**Nous recommandons vivement d’importer notre exemple d’auto-assignation** pour suivre le code au fur et à mesure que vous lisez ce document. Vous pouvez le faire dans `Unity Package Manager > Edgegap SDK > Samples` .
{% endhint %}

### Aperçu

Ce package comprend :

* Fichiers d’exécution - seront compilés et intégrés à vos builds client et serveur :
  * Utilitaires spécifiques au service :
    * [#server-agent](#server-agent "mention") - une intégration serveur complète à réutiliser/étendre,
    * [#client-agent](#client-agent "mention") - une intégration client complète à réutiliser/étendre.
    * Fonctions API - définitions des points de terminaison, gestion des erreurs et automatisations de journalisation.
    * Filter Compiler - utilitaires fortement typés pour créer des requêtes de filtre.
  * Spécifique au service DTO[^1] - conteneurs de données typés pour l’API Server Browser.
  * Utilitaires partagés - journalisation, HTTP, ping, observables, etc...
  * Partagé DTO[^1] - utilisé par plusieurs services Edgegap pour faire circuler les données.
* Fichiers d’exemple - inclus et compilés UNIQUEMENT s’ils sont importés dans votre projet :
  * [#auto-assign](#auto-assign "mention") - exemples de gestionnaires avec réservations auto-assignées,
  * [#custom-search](#custom-search "mention") - exemples de gestionnaires avec choix manuel de l’instance.

### Agent serveur

**La gestion du cycle de vie et de la capacité du serveur** est effectuée par l’agent serveur.

Une fois instancié, **le MonoBehaviour parent (gestionnaire) de l’agent doit initialiser l’agent** et fournir :

* `onMonitorUpdate`  callback - surveiller les changements de santé du service,
* `onInstanceUpdate`  callback - observer et réagir aux changements d’instance et de slot,
* `onConfirmationsUpdate`  callback - observer et réagir à l’authentification fédérée.

Une fois initialisé, cet agent fournira automatiquement les validations et branchera les observateurs de journalisation, pour finir par un appel unique au point de terminaison de l’API de monitoring afin d’indiquer l’état de santé du service.

Le gestionnaire de l’agent est censé prendre le contrôle et appeler les fonctions de l’agent à partir de ce point :

* `DiscoverInstance`  pour créer l’Instance serveur initiale et les slots, et lancer le heartbeat,
* `DeleteInstance`  une fois le match terminé / pour empêcher de nouveaux joueurs de rejoindre,
* `ConfirmReservation`  lorsque des joueurs rejoignent, afin de vérifier leur identité et l’attribution du slot,
* `UpdateSlot`  pour mettre à jour la capacité du slot (à l’arrivée / au départ d’un joueur) ou modifier les métadonnées,
* `UpdateInstance`  pour modifier les métadonnées de l’instance,
* `Status`  pour vérifier l’état de santé du service Server Browser.

{% hint style="success" %}
Les confirmations et les mises à jour des slots/de l’instance sont **placées en file d’attente et exécutées par lots par défaut** (mode Heartbeat) afin de maximiser l’évolutivité. Pour itérer plus rapidement pendant les tests de développement, utilisez le mode Greedy.
{% endhint %}

{% hint style="warning" %}
**Lors de la mise à jour des métadonnées, tous les indices doivent être définis.** Pour désactiver les clés non indexées, omettez-les simplement.
{% endhint %}

L’agent maintient automatiquement un heartbeat pour conserver la découvrabilité du serveur pendant son exécution. Si l’agent ne parvient pas à joindre votre Server Browser pendant plusieurs heartbeats consécutifs (configurable) :

* moins que le maximum - l’instance sera automatiquement redécouverte,
* plus que le maximum - l’instance sera automatiquement supprimée.

Lorsqu’une nouvelle connexion joueur est établie, le joueur est censé envoyer son ID de réservation (ID joueur tiers) au serveur de jeu en utilisant votre netcode, afin d’effectuer la confirmation de réservation.

Une fois `onConfirmationsUpdate`  déclenché, le gestionnaire doit effectuer des actions supplémentaires :

* appeler `UpdateSlot`  pour réduire les sièges disponibles pour tout slot avec des réservations confirmées,
* accepter ou refuser la connexion à l’aide des méthodes spécifiques au netcode.

Lorsqu’un joueur quitte la partie, le gestionnaire est censé augmenter le nombre de sièges disponibles pour ce slot.

{% hint style="info" %}
Accordez un court délai aux joueurs pour se reconnecter avant de considérer qu’ils ont abandonné en cas de plantages inattendus.
{% endhint %}

### Agent client

**La recherche d’instances, la pagination, le filtrage et les réservations** sont effectués par l’agent client.

Une fois instancié, **le MonoBehaviour parent (gestionnaire) de l’agent doit initialiser l’agent** et fournir :

* `onMonitorUpdate`  callback - surveiller les changements de santé du service,
* `onInstancesUpdate`  callback - observer et réagir aux changements de la liste d’instances.

Une fois initialisé, cet agent fournira automatiquement les validations et branchera les observateurs de journalisation, pour finir par un appel unique au point de terminaison de l’API de monitoring afin d’indiquer l’état de santé du service.

Le gestionnaire de l’agent est censé prendre le contrôle et appeler les fonctions de l’agent à partir de ce point :

* `ReserveSeats`  pour créer une réservation de capacité pour une instance/slot particulière ou en auto-assignation,
* `ListInstances`  pour lister les instances avec un filtre, un ordre, un curseur et une taille de page spécifiques,
* `GetNextPage`  pour récupérer davantage d’instances avec les paramètres actuels (filtres, etc.),
* `RefreshList`  pour vider le cache et recharger la première page, ou actualiser avec un curseur spécifique,
* `GetInstanceDetails`  pour récupérer les métadonnées et les informations de slots d’une instance spécifique,
* `Status`  pour vérifier l’état de santé du service Server Browser.

Lorsqu’une nouvelle connexion joueur est établie, le joueur est censé envoyer son ID de réservation (ID joueur tiers) au serveur de jeu en utilisant votre netcode, afin d’effectuer la confirmation de réservation.

{% hint style="success" %}
Enregistrez les détails de connexion dans le client ou le backend du jeu pour vous reconnecter en cas de plantage inattendu.
{% endhint %}

## 🧪 Exemples

Commencez avec des exemples incluant une intégration complète et fonctionnelle pour le serveur et le client.

### Auto-Assign

Utilise des réservations auto-assignées, le client ne spécifiant que le nom de la politique. Le Server Browser choisit automatiquement une instance correspondant au filtre de la politique et un slot avec suffisamment de places.

### Recherche personnalisée

Comprend une implémentation complète démontrant comment rechercher des instances et des slots, connecter les éléments de l’interface utilisateur, et laisser le joueur choisir manuellement où il souhaite réserver de la capacité.

## ⚙️ Personnalisation

Ce SDK est conçu pour être étendu et modifié, bien que certaines modifications puissent être risquées :

✅ Gestionnaire - connecter en toute sécurité les observateurs de l’interface et effectuer de petites additions ou modifications,

⚠️ Agent - modifier la gestion du cycle de vie et de la capacité à vos risques et périls,

⚠️ API - écrire votre propre intégration de zéro, en utilisant des utilitaires triés sur le volet.

Les gestionnaires peuvent observer tous les événements émis par les agents serveur et client comme décrit ci-dessous.

{% hint style="warning" %}
Assurez-vous de vous familiariser avec les concepts de [Server Browser approfondi](/docs.edgegap.com-fr/learn/server-browser.md) avant d’apporter des personnalisations.
{% endhint %}

### Événements serveur

L’agent serveur émet des événements (actions) que le gestionnaire parent doit observer et consommer.

Prévisualiser les événements émis par l’observable `Monitor` :

<table data-full-width="true"><thead><tr><th width="125">Type d’action</th><th width="450">Message de l’événement</th><th>Description</th></tr></thead><tbody><tr><td>🟢 <code>Mise à jour</code> </td><td><code>sain</code></td><td>Tous les systèmes sont opérationnels.</td></tr><tr><td>🟢 <code>Mise à jour</code> </td><td><code>malsain</code></td><td>Problème inattendu.</td></tr><tr><td>🔴 <code>Erreur</code></td><td><code>échec de récupération du monitor</code></td><td>Mauvaise configuration ou problème inattendu.</td></tr><tr><td>🟡 <code>Avertissement</code></td><td><code>délai d’attente de la requête limité au heartbeat [{timeout}]</code></td><td>Empêche les conditions de concurrence.</td></tr></tbody></table>

Prévisualiser les événements (actions) émis par l’observable `Instance`:

<table data-full-width="true"><thead><tr><th width="125">Type d’action</th><th width="450">Message de l’événement</th><th>Description</th></tr></thead><tbody><tr><td>🟢 <code>Mise à jour</code> </td><td><code>découverte</code></td><td><a href="/pages/7a8a569cdd7738220b9ebc8162027e9dca4d1518#discover-instance">Découverte de l’instance</a> terminée avec succès. Peut être déclenchée si l’instance a perdu la connexion en raison d’une condition temporaire puis a été redécouverte.</td></tr><tr><td>🔴 <code>Erreur</code></td><td><code>doublon de découverte</code></td><td>Une instance avec cet ID de requête est déjà découverte.</td></tr><tr><td>🔴 <code>Erreur</code></td><td><code>échec de la découverte</code></td><td>Problème inattendu lors de la découverte.</td></tr><tr><td>🔵 <code>Notification</code></td><td><code>heartbeat OK</code></td><td>Heartbeat terminé avec succès.</td></tr><tr><td>🟡 <code>Avertissement</code></td><td><code>échec du heartbeat [{consecutive}/{maximum}]</code></td><td>Échec du heartbeat, le serveur n’a pas pu joindre le Server Browser.</td></tr><tr><td>🔵 <code>Notification</code></td><td><code>mise à jour de l’instance mise en file d’attente</code></td><td>Mise à jour de l’instance mise en file d’attente pour le prochain lot (heartbeat/greedy).</td></tr><tr><td>🟢 <code>Mise à jour</code> </td><td><code>instance mise à jour</code></td><td>Métadonnées de l’instance mises à jour avec succès.</td></tr><tr><td>🔴 <code>Erreur</code></td><td><code>échec de mise à jour de l’instance, mise en file d’attente pour réessai</code></td><td>Échec de la mise à jour de l’instance, possiblement à cause d’une limitation de débit ou d’une erreur.</td></tr><tr><td>🟢 <code>Mise à jour</code> </td><td><code>instance supprimée</code></td><td>L’instance n’est plus découvrable par les joueurs.</td></tr><tr><td>🟢 <code>Mise à jour</code> </td><td><code>échec de suppression de l’instance (introuvable)</code></td><td>L’instance a peut-être expiré en raison d’un trop grand nombre de heartbeats manqués.</td></tr><tr><td>🔴 <code>Erreur</code></td><td><code>échec de suppression de l’instance</code></td><td>Échec de la suppression de l’instance, possiblement à cause d’une limitation de débit ou d’une erreur.</td></tr><tr><td>🔵 <code>Notification</code></td><td><code>mise à jour du slot mise en file d’attente [{slot}]</code></td><td>Mise à jour du slot mise en file d’attente pour le prochain lot (heartbeat/greedy).</td></tr><tr><td>🟢 <code>Mise à jour</code> </td><td><code>slot mis à jour [{slot}]</code></td><td>La capacité en sièges du slot et/ou ses métadonnées ont été mises à jour avec succès.</td></tr><tr><td>🟡 <code>Avertissement</code></td><td><code>l’agent a limité en concurrent la mise à jour du slot</code></td><td>Tentative de mise à jour concurrente empêchée (condition de concurrence).</td></tr><tr><td>🔴 <code>Erreur</code></td><td><code>échec de mise à jour du slot (introuvable) [{slot}]</code></td><td>Aucun slot de ce nom n’est encore défini pour cette instance.</td></tr><tr><td>🔴 <code>Erreur</code></td><td><code>échec de mise à jour du slot (pas assez de sièges) [{slot}]</code></td><td>La mise à jour du slot a tenté de réduire le nombre de sièges disponibles en dessous de zéro.</td></tr><tr><td>🔴 <code>Erreur</code></td><td><code>échec de mise à jour du slot, mise en file d’attente pour réessai [{slot}]</code></td><td>Échec de la mise à jour du slot, possiblement à cause d’une limitation de débit ou d’une erreur.</td></tr></tbody></table>

Prévisualiser les événements (actions) émis par l’observable `Confirmations`:

<table data-full-width="true"><thead><tr><th width="125">Type d’action</th><th width="450">Message de l’événement</th><th>Description</th></tr></thead><tbody><tr><td>🔵 <code>Notification</code></td><td><code>mis en file d’attente [{player}]</code></td><td>Confirmation mise en file d’attente pour le prochain lot (heartbeat/greedy).</td></tr><tr><td>🟡 <code>Avertissement</code></td><td><code>doublon [{player}]</code></td><td>Tentative de confirmation en double empêchée (déjà en file d’attente).</td></tr><tr><td>🟢 <code>Mise à jour</code> </td><td><code>confirmé</code></td><td>Réservations confirmées pour des slots individuels, inclut également les ID de joueurs expirés et inconnus que le gestionnaire doit traiter (accepter/expulser).</td></tr><tr><td>🔴 <code>Erreur</code></td><td><code>échec</code></td><td>Problème inattendu avec les confirmations. Vérifiez l’état du service.</td></tr></tbody></table>

### Événements client

L’agent client émet des événements (actions) que le gestionnaire parent doit observer et consommer.

Prévisualiser les événements émis par l’observable `Monitor` :

<table data-full-width="true"><thead><tr><th width="125">Type d’action</th><th width="450">Message de l’événement</th><th>Description</th></tr></thead><tbody><tr><td>🟢 <code>Mise à jour</code> </td><td><code>sain</code></td><td>Tous les systèmes sont opérationnels.</td></tr><tr><td>🟢 <code>Mise à jour</code> </td><td><code>malsain</code></td><td>Problème inattendu.</td></tr><tr><td>🔴 <code>Erreur</code></td><td><code>échec de récupération du monitor</code></td><td>Mauvaise configuration ou problème inattendu.</td></tr></tbody></table>

Prévisualiser les événements émis par l’observable `Instances`:

<table data-full-width="true"><thead><tr><th width="125">Type d’action</th><th width="450">Message de l’événement</th><th>Description</th></tr></thead><tbody><tr><td>🔵 <code>Notification</code></td><td><code>sièges réservés</code></td><td>Réservation de sièges réussie.</td></tr><tr><td>🔴 <code>Erreur</code></td><td><code>échec de réservation des sièges (introuvable)</code></td><td><a data-mention href="#auto-assign">#auto-assign</a> - nom de politique introuvable (supprimée ou inactive). <a data-mention href="#custom-search">#custom-search</a> - instance ou slot introuvable.</td></tr><tr><td>🔴 <code>Erreur</code></td><td><code>échec de réservation des sièges (capacité atteinte)</code></td><td><a data-mention href="#auto-assign">#auto-assign</a> - la politique a atteint sa capacité maximale. <a data-mention href="#custom-search">#custom-search</a> - le slot a atteint sa capacité maximale.</td></tr><tr><td>🔴 <code>Erreur</code></td><td><code>échec de réservation des sièges</code></td><td>Échec de la réservation des sièges, possiblement en raison d’une politique, d’un ID de requête ou d’un ID de slot invalide.</td></tr><tr><td>🟢 <code>Mise à jour</code> </td><td><code>liste des instances récupérée</code></td><td>Liste des instances récupérée avec succès.</td></tr><tr><td>🟢 <code>Mise à jour</code> </td><td><code>page suivante de la liste des instances récupérée</code></td><td>Page suivante des instances récupérée avec succès.</td></tr><tr><td>🔴 <code>Erreur</code></td><td><code>dernière page de la liste des instances atteinte</code></td><td>Échec de la récupération de la page suivante, essayez d’actualiser ou de modifier les filtres.</td></tr><tr><td>🔴 <code>Erreur</code></td><td><code>échec de récupération de la page suivante de la liste d’instances</code></td><td>Échec de la récupération de la page suivante, possiblement à cause d’un curseur invalide.</td></tr><tr><td>🟢 <code>Mise à jour</code> </td><td><code>détails de l’instance récupérés</code></td><td>Détails d’une instance listée récupérés avec succès.</td></tr><tr><td>🟢 <code>Mise à jour</code> </td><td><code>instance non mise en cache, insertion au début</code></td><td>Détails récupérés d’une instance hors de la liste actuelle.</td></tr><tr><td>🔴 <code>Erreur</code></td><td><code>échec de récupération des détails de l’instance</code></td><td>Échec de récupération des détails, possiblement à cause d’un ID de requête invalide.</td></tr></tbody></table>

[^1]: Objet de transfert de données


---

# 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-fr/unity/server-browser.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.
