# Archipelago

Archipelago es el servicio de realm que agrupa a los jugadores cercanos en islas, reasignándolos a medida que se desplazan y proporcionando la información necesaria para conectarse al backend real que retransmitirá sus mensajes.

{% hint style="info" %}
Puedes ver el protocolo Archipelago en acción y experimentar con él usando el código abierto [Comms Station](https://decentraland.github.io/comms-station/).
{% endhint %}

Para usar el servicio, los clientes deben conectarse al endpoint websocket de Archipelago de su realm y autenticarse para comenzar su sesión. Luego pueden empezar a enviar actualizaciones posicionales y recibir asignaciones de isla (ver el [ciclo de vida del cliente](https://github.com/decentraland/docs/blob/main/contributor/communications/overview/README.md#lifecycle)).

Todos los mensajes intercambiados con el servicio Archipelago están codificados usando protocol buffers, según se define en el [repositorio del protocolo](https://github.com/decentraland/protocol).

### Conexión <a href="#connecting" id="connecting"></a>

Para empezar, los clientes deben abrir una conexión websocket segura (`wss:`) al `/archipelago/ws` endpoint del realm.

Una vez conectados, los clientes tienen una ventana temporal definida por la política del realm (60 segundos, por defecto) para enviar cada mensaje del [flujo de autenticación](#authenticating) .

{% hint style="warning" %}
Mientras que los realms más grandes ejecutan el servicio Archipelago, los más pequeños pueden optar por proporcionar una cadena de conexión de backend fija para todos los jugadores. La URI, si está presente, puede encontrarse en la `comms.fixedAdapter` propiedad del `/about`.
{% endhint %}

En estos casos, la asignación dinámica de islas no estará disponible, y la interfaz RPC del realm no debe usarse con ese propósito.

### Autenticación <a href="#authenticating" id="authenticating"></a>

Después de abrir una conexión a Archipelago, los clientes deben comenzar solicitando y firmando un desafío del servicio para verificar su identidad.

El primer mensaje que envía un cliente es un [`ChallengeRequestMessage`](https://github.com/decentraland/docs/blob/main/contributor/communications/ChallengeRequestMessage/README.md) con su dirección de Ethereum (es decir, su clave pública). Recibirán un [`ChallengeResponseMessage`](https://github.com/decentraland/docs/blob/main/contributor/communications/ChallengeResponseMessage/README.md) con una cadena generada aleatoriamente para firmar, y deben responder con un [`SignedChallengeMessage`](#SignedChallengeMessage).

El [`SignedChallengeMessage`](#SignedChallengeMessage) lleva un [auth chain](https://github.com/decentraland/docs/blob/main/contributor/auth/authchain/README.md) serializado en JSON que comienza con la dirección proporcionada y termina con la firma del desafío.

Si la firma es verificada con éxito por el servicio, el cliente queda autenticado y recibirá un [`WelcomeMessage`](#WelcomeMessage).

{% @mermaid/diagram content="sequenceDiagram
participant Client
participant Archipelago

```
Note over Client,Archipelago: Connect
Client->>Archipelago: ChallengeRequestMessage
Archipelago->>Client: ChallengeResponseMessage
Client->>Archipelago: SignedChallengeMessage
Archipelago->>Client: WelcomeMessage" %}
```

### Envío de latido (Heartbeat) <a href="#heartbeat" id="heartbeat"></a>

Durante su sesión, los clientes deben enviar periódicamente un [`Heartbeat`](#Heartbeat) mensaje para mantener a Archipelago actualizado con la información necesaria para emitir asignaciones de isla.

{% hint style="info" %}
La frecuencia de heartbeat recomendada para clientes de comms es de aproximadamente una actualización por segundo.
{% endhint %}

Si un cliente deja de enviar [`Heartbeat`](#Heartbeat) mensajes, Archipelago (dependiendo de su política actual) puede cerrar la conexión.

### Obtención de asignaciones de isla <a href="#assignment" id="assignment"></a>

Poco después del primer heartbeat, Archipelago enviará al cliente su primera [`IslandChangedMessage`](https://github.com/decentraland/protocol/blob/9a568b16b2eafb134177329ba670c1451be8a169/proto/decentraland/kernel/comms/v3/archipelago.proto#L17).

El campo principal es `conn_str`, que puede usarse para inicializar un transporte y conectarse a la isla. Los valores típicamente se ven así:

```
livekit:wss://comms.example.com?access_token=eyJhbGciOiJI...
```

La etiqueta antes del primer `:` es el tipo de transporte, el resto es una URI especializada para él. Puede incluir tokens preautorizados u otros parámetros.

Durante la sesión, Archipelago puede enviar una nueva asignación en cualquier momento, por varias razones:

1. Cambios de posición: el cliente reportó alejarse de otros en la isla.
2. Solicitudes de isla: el cliente solicitó ser asignado a una isla específica.
3. Política de Archipelago: el servicio decidió crear o dividir islas para equilibrar mejor la población.

Los clientes deben escuchar estas asignaciones, cerrando y abriendo conexiones de transporte según se indique, y cambiando el tipo de transporte en uso cuando sea necesario.

### Mensajes del cliente

**`ChallengeRequestMessage`** [**↗ fuente**](https://github.com/decentraland/protocol/blob/9a568b16b2eafb134177329ba670c1451be8a169/proto/decentraland/kernel/comms/v3/archipelago.proto#L54)

Enviado por el cliente como el primer mensaje de una sesión, para iniciar el flujo de autenticación.

| Campo     | Tipo     | Valor                     |
| --------- | -------- | ------------------------- |
| `address` | `string` | La dirección del usuario. |

El `address` el campo debe derivarse de la primera clave privada del [auth chain](https://github.com/decentraland/docs/blob/main/contributor/auth/authchain/README.md) que se presentará.

***

**`SignedChallengeMessage`** [**↗ fuente**](https://github.com/decentraland/protocol/blob/9a568b16b2eafb134177329ba670c1451be8a169/proto/decentraland/kernel/comms/v3/archipelago.proto#L58)

Enviado por el cliente después de recibir un [`ChallengeResponseMessage`](#ChallengeResponseMessage), para completar el flujo de autenticación.

| Campo             | Tipo     | Valor                                                                                                                                                          |
| ----------------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `auth_chain_json` | `string` | Un [auth chain](https://github.com/decentraland/docs/blob/main/contributor/auth/authchain/README.md) serializado en JSON que termina con la firma del desafío. |

La primera clave en la [auth chain](https://github.com/decentraland/docs/blob/main/contributor/auth/authchain/README.md) debe corresponder a la dirección enviada en el [`ChallengeRequestMessage`](#ChallengeRequestMessage).

***

**`Heartbeat`** [**↗ fuente**](https://github.com/decentraland/protocol/blob/9a568b16b2eafb134177329ba670c1451be8a169/proto/decentraland/kernel/comms/v3/archipelago.proto#L62)

original.

| Campo                                                                                                                                                                    | Tipo           | Valor    |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------- | -------- |
| `Enviado por el cliente a intervalos regulares (típicamente una vez por segundo), para actualizar a Archipelago sobre su posición y/o solicitar una asignación de isla.` | `position`     | Position |
| `La posición 3D del cliente en el mapa del mundo`                                                                                                                        | `desired_room` | string?  |

El ID de una isla a la que el cliente le gustaría ser asignado `Heartbeat` El primer [`IslandChangedMessage`](#IslandChangedMessage) mensaje que un cliente envía es seguido rápidamente por un `Heartbeat` de Archipelago. Sin embargo, las actualizaciones subsecuentes son independientes de las asignaciones de isla. Los clientes no deberían esperar que un

sea respondido. `La posición 3D del cliente en el mapa del mundo` Cuando se incluye el parámetro

### , el servicio intentará atender la solicitud, pero no se garantiza una reasignación a esa isla. Depende de la política de Archipelago (por ejemplo, límites de población en la isla).

**`ChallengeResponseMessage`** [**↗ fuente**](https://github.com/decentraland/protocol/blob/9a568b16b2eafb134177329ba670c1451be8a169/proto/decentraland/kernel/comms/v3/archipelago.proto#L8)

Mensajes del servidor [`ChallengeRequestMessage`](#ChallengeRequestMessage)

| Campo                                        | Tipo                | Valor                                                                                                                 |
| -------------------------------------------- | ------------------- | --------------------------------------------------------------------------------------------------------------------- |
| `Enviado por Archipelago en respuesta a un`  | `string`            | challenge\_to\_sign [auth chain](https://github.com/decentraland/docs/blob/main/contributor/auth/authchain/README.md) |
| `Una cadena generada para firmar y crear un` | `already_connected` | bool                                                                                                                  |

***

**`WelcomeMessage`** [**↗ fuente**](https://github.com/decentraland/protocol/blob/9a568b16b2eafb134177329ba670c1451be8a169/proto/decentraland/kernel/comms/v3/archipelago.proto#L13)

Si existe una conexión previa para la clave de este usuario

| Campo                                                           | Tipo     | Valor    |
| --------------------------------------------------------------- | -------- | -------- |
| `Enviado por Archipelago después de una autenticación exitosa.` | `string` | peer\_id |

***

**`IslandChangedMessage`** [**↗ fuente**](https://github.com/decentraland/protocol/blob/9a568b16b2eafb134177329ba670c1451be8a169/proto/decentraland/kernel/comms/v3/archipelago.proto#L17)

Un identificador único para el cliente autenticado (típicamente su dirección)

Enviado por Archipelago cuando el cliente es (re)asignado a una isla.

| Campo                                | Tipo           | Valor                                                                                                                                                               |
| ------------------------------------ | -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `Descripción.`                       | `string`       | island\_id                                                                                                                                                          |
| `El ID de la nueva isla`             | `desired_room` | from\_island\_id                                                                                                                                                    |
| `conn_str`                           | `string`       | El ID de la isla anterior, si esto es una reasignación [transport](https://github.com/decentraland/docs/blob/main/contributor/communications/transports/README.md). |
| `La cadena de conexión para la isla` | `peers`        | Enviado por Archipelago cuando el cliente es (re)asignado a una isla.                                                                                               |

map\<string, Position> `IslandChangedMessage` Los clientes que reciben un `conn_str`.

El `La cadena de conexión para la isla` deben terminar su conexión con el backend de la isla y conectarse al indicado en [transport](https://github.com/decentraland/docs/blob/main/contributor/communications/transports/README.md) El campo contiene las identidades y posiciones actuales de todos los pares en la isla, para que los clientes puedan poblar su conjunto inicial. Después de este punto, deben depender de los mensajes recibidos a través de la

***

**`island`** [**↗ fuente**](https://github.com/decentraland/protocol/blob/9a568b16b2eafb134177329ba670c1451be8a169/proto/decentraland/kernel/comms/v3/archipelago.proto#LL37C1-L38C1)

para obtener actualizaciones posicionales.

| Campo           | Tipo                                                    | Valor  |
| --------------- | ------------------------------------------------------- | ------ |
| `KickedMessage` | `Enviado por Archipelago antes de cerrar una conexión.` | reason |

KickedReason `KickedMessage` La razón de Archipelago para cerrar la conexión

* `Los valores estándar para el`campo son:

***

**`KR_NEW_SESSION`** [**↗ fuente**](https://github.com/decentraland/protocol/blob/9a568b16b2eafb134177329ba670c1451be8a169/proto/decentraland/kernel/comms/v3/archipelago.proto#L29)

: otra conexión autenticada con la misma clave.

| Campo                                                           | Tipo     | Valor                                                                    |
| --------------------------------------------------------------- | -------- | ------------------------------------------------------------------------ |
| `Descripción.`                                                  | `string` | JoinIslandMessage                                                        |
| `Enviado por Archipelago después de una autenticación exitosa.` | `string` | Enviado por Archipelago cuando un par es asignado a la isla del cliente. |

El `Descripción.` El identificador de la isla

***

**`El identificador único del par (típicamente su dirección)`** [**↗ fuente**](https://github.com/decentraland/protocol/blob/9a568b16b2eafb134177329ba670c1451be8a169/proto/decentraland/kernel/comms/v3/archipelago.proto#L24)

El campo coincidirá con la asignación actual del cliente. LeftIslandMessage Enviado por Archipelago cuando un par es removido de la isla del cliente.

| Campo                                                           | Tipo     | Valor                                                                    |
| --------------------------------------------------------------- | -------- | ------------------------------------------------------------------------ |
| `Descripción.`                                                  | `string` | JoinIslandMessage                                                        |
| `Enviado por Archipelago después de una autenticación exitosa.` | `string` | Enviado por Archipelago cuando un par es asignado a la isla del cliente. |

El `Descripción.` El identificador de la isla
