> ## Documentation Index
> Fetch the complete documentation index at: https://docs.base44.com/llms.txt
> Use this file to discover all available pages before exploring further.

> ## Agent Instructions
> Internal links on these pages omit the .md extension. Append .md to a docs page URL, or send an Accept: text/markdown header, to get that page as markdown.

# Actores: flujos de ejemplo

> Flujos de ejemplo para manejadores del ciclo de vida, temporizadores, conexiones, almacenamiento, entidades y funciones de backend

<div className="dev-docs-banner">
  <div className="dev-docs-banner-content">
    <div className="dev-docs-banner-title">
      Estás viendo la documentación para desarrolladores
    </div>

    <div className="dev-docs-banner-text">
      Esta documentación es para desarrolladores que trabajan con la plataforma para desarrolladores de Base44.
    </div>
  </div>
</div>

Usa estos flujos de ejemplo como punto de partida para tu implementación.

## Conectar un cliente a una sesión

Cuando el frontend necesita unirse a una sesión en vivo, recibir mensajes del actor y enviarle mensajes, conecta un cliente a una sesión de actor.

**Para conectar un cliente a una sesión:**

1. Llama a [`base44.actors.ActorName(sessionId)`](/es/developers/references/sdk/docs/type-aliases/actors) para seleccionar la sesión.
2. Llama a [`.connect()`](/es/developers/references/sdk/docs/type-aliases/actors#connect) para abrir la conexión WebSocket.
3. Llama a [`conn.subscribe()`](/es/developers/references/sdk/docs/type-aliases/actors#subscribe) para registrar un listener para los mensajes del actor.
4. Llama a [`conn.send()`](/es/developers/references/sdk/docs/type-aliases/actors#send) para enviar un mensaje al actor.

El siguiente ejemplo se conecta a una sesión del actor `chatRoom`, escucha los mensajes y envía un mensaje:

```typescript theme={null}
const conn = base44.actors.chatRoom("lobby-1").connect();

conn.subscribe((msg) => {
  if (msg.type === "message") console.log(msg.text);
});

conn.send({ type: "message", text: "Hello" });
```

Para más información sobre las conexiones, consulta [conexiones](/es/developers/backend/resources/actors/reference#connections).

## Ejecutar ticks

Cuando un trabajo debe repetirse en un intervalo mientras hay clientes en la sesión, ejecuta ticks. Por ejemplo, para difundir el estado de un juego o actualizar un temporizador de ronda.

**Para ejecutar ticks:**

1. Define [`tickIntervalMs`](/es/developers/backend/resources/actors/reference#timer-handlers-and-settings) con la duración del intervalo en milisegundos.
2. Implementa [`shouldTick()`](/es/developers/backend/resources/actors/reference#timer-handlers-and-settings) para que devuelva `true` para seguir con los ticks y `false` para detenerlos.
3. En [`handleTick()`](/es/developers/backend/resources/actors/reference#timer-handlers-and-settings), ejecuta el trabajo de cada intervalo.

El siguiente ejemplo ejecuta un tick cada segundo mientras hay al menos dos clientes en la sesión, y difunde una cuenta atrás en cada tick:

```typescript theme={null}
export default class Game extends Actor<Incoming, Outgoing> {
  tickIntervalMs = 1000;
  countdown = 60;

  shouldTick() {
    return this.getConnections().length >= 2;
  }

  async handleTick() {
    this.countdown--;
    this.broadcast({ type: "tick", countdown: this.countdown });
  }
}
```

Para más información sobre los ticks, consulta [manejadores y configuración de temporizadores](/es/developers/backend/resources/actors/reference#timer-handlers-and-settings).

## Programar despertares

Cuando un trabajo debe ejecutarse una vez a una hora concreta, tanto si la sesión está activa como inactiva, programa un despertar. Por ejemplo, para terminar un turno después de 30 segundos o cerrar una sala de espera vacía.

**Para programar un despertar:**

1. Llama a [`schedule()`](/es/developers/backend/resources/actors/reference#timer-handlers-and-settings) con una clave y una hora para programar el despertar.
2. En [`handleWake()`](/es/developers/backend/resources/actors/reference#timer-handlers-and-settings), comprueba la clave y ejecuta el trabajo de ese despertar.
3. Cuando el despertar ya no sea necesario, llama a [`cancelSchedule()`](/es/developers/backend/resources/actors/reference#timer-handlers-and-settings) con la clave.

El siguiente ejemplo programa un tiempo límite de turno cuando empieza un turno y difunde un mensaje cuando se activa el tiempo límite:

```typescript theme={null}
export default class Game extends Actor<Incoming, Outgoing> {
  async handleMessage(_conn, msg) {
    if (msg.type === "start-turn") {
      await this.schedule("turn-timeout", Date.now() + 30_000);
    }
    if (msg.type === "end-turn") {
      await this.cancelSchedule("turn-timeout");
    }
  }

  async handleWake(key: string) {
    if (key === "turn-timeout") {
      this.broadcast({ type: "timeout" });
    }
  }
}
```

Para más información sobre los despertares, consulta [manejadores y configuración de temporizadores](/es/developers/backend/resources/actors/reference#timer-handlers-and-settings).

## Gestionar las conexiones de clientes

Cuando necesitas decidir quién puede unirse a una sesión, responder a un cliente concreto y llegar a todos los clientes de la sesión, gestiona las conexiones de clientes.

**Para gestionar las conexiones de clientes:**

1. En [`handleConnect()`](/es/developers/backend/resources/actors/reference#lifecycle-handlers), comprueba [`conn.identity`](/es/developers/backend/resources/actors/reference#connections) y llama a [`conn.reject()`](/es/developers/backend/resources/actors/reference#connections) para rechazar a un cliente.
2. Llama a [`conn.send()`](/es/developers/backend/resources/actors/reference#connections) para responder solo a ese cliente.
3. En [`handleMessage()`](/es/developers/backend/resources/actors/reference#lifecycle-handlers), llama a [`broadcast()`](/es/developers/backend/resources/actors/reference#connections) para llegar a todos los clientes conectados. Para identificar al remitente, incluye campos de `conn` en el mensaje.

El siguiente ejemplo rechaza a los clientes anónimos, envía el historial al cliente que se conecta y difunde los mensajes con el ID de usuario del remitente:

```typescript theme={null}
async handleConnect(conn) {
  if (conn.identity.type === "anonymous") {
    conn.reject(401, "Login required");
    return;
  }
  conn.send({ type: "history", messages: this.messages });
}

async handleMessage(conn, msg) {
  this.broadcast({ type: "message", from: conn.identity.userId, text: msg.text });
}
```

Para más información sobre las conexiones, consulta [conexiones](/es/developers/backend/resources/actors/reference#connections).

## Conservar los datos de sesión

Cuando los valores deben sobrevivir a un periodo de inactividad, conserva los datos de sesión. Por ejemplo, un tablero, una lista de historial o el turno actual.

**Para conservar los datos de sesión:**

1. En [`handleStart()`](/es/developers/backend/resources/actors/reference#lifecycle-handlers), carga los valores de [`this.storage`](/es/developers/backend/resources/actors/reference#storage) en los campos de clase.
2. Después de cada cambio, llama a [`this.storage.put()`](/es/developers/backend/resources/actors/reference#storage) para guardar el valor actualizado.
3. Para reiniciar la sesión, llama a [`this.storage.delete()`](/es/developers/backend/resources/actors/reference#storage) o [`this.storage.deleteAll()`](/es/developers/backend/resources/actors/reference#storage).

El siguiente ejemplo carga un tablero al inicio, lo guarda después de cada movimiento y vacía el almacenamiento cuando se desconecta el último cliente:

```typescript theme={null}
async handleStart() {
  this.board = (await this.storage.get<Board>("board")) ?? newBoard();
}

async handleMessage(_conn, msg) {
  applyMove(this.board, msg.move);
  await this.storage.put("board", this.board);
}

async handleClose(_conn) {
  if (this.getConnections().length === 0) {
    await this.storage.deleteAll();
  }
}
```

Para más información sobre el almacenamiento, consulta [almacenamiento](/es/developers/backend/resources/actors/reference#storage).

## Escribir datos de entidades desde una sesión

Cuando la sesión necesita crear o actualizar registros de la app, escribe datos de entidades. Por ejemplo, una puntuación final o un pedido completado.

**Para escribir datos de entidades desde una sesión:**

1. Valida el mensaje entrante antes de escribir.
2. Lee el ID de usuario de [`conn.identity.userId`](/es/developers/backend/resources/actors/reference#connections).
3. Usa [`this.client.asServiceRole`](/es/developers/backend/resources/actors/reference#entity-access) para obtener acceso elevado. Escribe con una clave estable, como el ID de sesión, para que un manejador repetido actualice el mismo registro.

El siguiente ejemplo guarda una puntuación final para el cliente autenticado. Un guardado posterior para la misma sesión actualiza ese registro:

```typescript theme={null}
async handleMessage(conn, msg) {
  if (msg.type !== "save-score" || conn.identity.type !== "authenticated") return;
  if (typeof msg.score !== "number") return;

  const fields = {
    sessionId: this.instanceId,
    userId: conn.identity.userId,
    score: msg.score,
  };
  const [existing] = await this.client.asServiceRole.entities.Score.filter({
    sessionId: this.instanceId,
  });

  if (existing) {
    await this.client.asServiceRole.entities.Score.update(existing.id, fields);
  } else {
    await this.client.asServiceRole.entities.Score.create(fields);
  }
}
```

Para más información sobre el acceso a entidades, consulta [acceso a entidades](/es/developers/backend/resources/actors/reference#entity-access).

## Llamar a una función de backend para trabajo con secretos

Los actores pueden leer los secretos de la app con [`secrets.get()`](/es/developers/backend/resources/actors/reference#read-secrets). Cuando un manejador necesita un trabajo que usa un secreto, como llamar a una API externa con una clave de API, te recomendamos llamar a una [función de backend](/es/developers/backend/resources/backend-functions/overview). La función lee el secreto y devuelve el resultado, nunca el secreto.

**Para llamar a una función de backend desde un actor:**

1. Crea una función de backend que lea el secreto con `secrets.get()`, haga el trabajo y devuelva el resultado.
2. En un manejador, llama a [`this.client.functions.invoke()`](/es/developers/references/sdk/docs/interfaces/functions#invoke) con el nombre de la función y los datos que quieres enviar.
3. Usa el resultado en tu sesión, por ejemplo, difundiéndolo a los clientes conectados.

El siguiente ejemplo muestra una función de backend que lee una clave de API y devuelve una traducción:

```typescript theme={null}
// base44/functions/translateText/entry.ts
import { secrets } from "base44:runtime";

export default async function (req: Request): Promise<Response> {
  const { text } = await req.json();
  const apiKey = secrets.get("TRANSLATE_API_KEY");

  const res = await fetch("https://api.example.com/translate", {
    method: "POST",
    headers: { Authorization: `Bearer ${apiKey}` },
    body: JSON.stringify({ text }),
  });
  const { translation } = await res.json();

  return Response.json({ translation });
}
```

El siguiente ejemplo llama a esa función desde un actor y difunde el resultado:

```typescript theme={null}
export default class ChatRoom extends Actor<Incoming, Outgoing> {
  async handleMessage(_conn, msg) {
    const result = await this.client.functions.invoke("translateText", { text: msg.text });
    this.broadcast({ type: "message", text: result.data.translation });
  }
}
```

## Ver también

* [Resumen de actores](/es/developers/backend/resources/actors/overview): Conceptos y terminología
* [Crear un actor](/es/developers/backend/resources/actors/create-actor): Archivos del actor y una clase mínima
* [Archivos y código de actores](/es/developers/backend/resources/actors/reference): API completa de la clase de backend
* [`actors deploy`](/es/developers/references/cli/commands/actors-deploy): Despliega los actores locales

<Note>Esta página fue traducida con IA. Para obtener la información más precisa y actualizada, consulta la [versión en inglés](/). </Note>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.