> ## 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.

# Actor: flussi di esempio

> Flussi di esempio per handler del ciclo di vita, timer, connessioni, storage, entità e funzioni backend

<div className="dev-docs-banner">
  <div className="dev-docs-banner-content">
    <div className="dev-docs-banner-title">
      Stai visualizzando la documentazione per sviluppatori
    </div>

    <div className="dev-docs-banner-text">
      Questa documentazione è per sviluppatori che lavorano con la piattaforma
      per sviluppatori di Base44.
    </div>
  </div>
</div>

Usa questi flussi di esempio come punto di partenza per la tua implementazione.

## Connettere un client a una sessione

Quando il frontend deve unirsi a una sessione live, ricevere messaggi dall'actor e inviare messaggi all'actor, connetti un client a una sessione dell'actor.

**Per connettere un client a una sessione:**

1. Chiama [`base44.actors.ActorName(sessionId)`](/it/developers/references/sdk/docs/type-aliases/actors) per selezionare la sessione.
2. Chiama [`.connect()`](/it/developers/references/sdk/docs/type-aliases/actors#connect) per aprire la connessione WebSocket.
3. Chiama [`conn.subscribe()`](/it/developers/references/sdk/docs/type-aliases/actors#subscribe) per registrare un listener per i messaggi dell'actor.
4. Chiama [`conn.send()`](/it/developers/references/sdk/docs/type-aliases/actors#send) per inviare un messaggio all'actor.

L'esempio seguente si connette a una sessione dell'actor `chatRoom`, ascolta i messaggi e invia un messaggio:

```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" });
```

Per saperne di più sulle connessioni, consulta [connessioni](/it/developers/backend/resources/actors/reference#connections).

## Eseguire i tick

Quando un'operazione deve ripetersi a intervalli mentre i client sono nella sessione, esegui i tick. Ad esempio, per trasmettere lo stato del gioco o aggiornare il timer di un round.

**Per eseguire i tick:**

1. Imposta [`tickIntervalMs`](/it/developers/backend/resources/actors/reference#timer-handlers-and-settings) sulla durata dell'intervallo in millisecondi.
2. Implementa [`shouldTick()`](/it/developers/backend/resources/actors/reference#timer-handlers-and-settings) in modo che restituisca `true` per continuare i tick e `false` per fermarli.
3. In [`handleTick()`](/it/developers/backend/resources/actors/reference#timer-handlers-and-settings), esegui l'operazione per ogni intervallo.

L'esempio seguente esegue un tick ogni secondo mentre almeno due client sono nella sessione, trasmettendo un conto alla rovescia a ogni 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 });
  }
}
```

Per saperne di più sui tick, consulta [handler e impostazioni dei timer](/it/developers/backend/resources/actors/reference#timer-handlers-and-settings).

## Pianificare i wake

Quando un'operazione deve essere eseguita una volta in un momento specifico, sia che la sessione sia attiva sia che sia inattiva, pianifica un wake. Ad esempio, per terminare un turno dopo 30 secondi o chiudere una lobby vuota.

**Per pianificare un wake:**

1. Chiama [`schedule()`](/it/developers/backend/resources/actors/reference#timer-handlers-and-settings) con una chiave e un orario per impostare il wake.
2. In [`handleWake()`](/it/developers/backend/resources/actors/reference#timer-handlers-and-settings), controlla la chiave ed esegui l'operazione per quel wake.
3. Quando il wake non serve più, chiama [`cancelSchedule()`](/it/developers/backend/resources/actors/reference#timer-handlers-and-settings) con la chiave.

L'esempio seguente pianifica un timeout del turno quando un turno inizia e trasmette un messaggio quando il timeout si attiva:

```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" });
    }
  }
}
```

Per saperne di più sui wake, consulta [handler e impostazioni dei timer](/it/developers/backend/resources/actors/reference#timer-handlers-and-settings).

## Gestire le connessioni dei client

Quando devi decidere chi può unirsi a una sessione, rispondere a un client specifico e raggiungere tutti i client della sessione, gestisci le connessioni dei client.

**Per gestire le connessioni dei client:**

1. In [`handleConnect()`](/it/developers/backend/resources/actors/reference#lifecycle-handlers), controlla [`conn.identity`](/it/developers/backend/resources/actors/reference#connections) e chiama [`conn.reject()`](/it/developers/backend/resources/actors/reference#connections) per rifiutare un client.
2. Chiama [`conn.send()`](/it/developers/backend/resources/actors/reference#connections) per rispondere solo a quel client.
3. In [`handleMessage()`](/it/developers/backend/resources/actors/reference#lifecycle-handlers), chiama [`broadcast()`](/it/developers/backend/resources/actors/reference#connections) per raggiungere tutti i client connessi. Per identificare il mittente, includi nel messaggio campi di `conn`.

L'esempio seguente rifiuta i client anonimi, invia la cronologia al client che si connette e trasmette i messaggi con l'ID utente del mittente:

```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 });
}
```

Per saperne di più sulle connessioni, consulta [connessioni](/it/developers/backend/resources/actors/reference#connections).

## Rendere persistenti i dati di sessione

Quando dei valori devono sopravvivere a un periodo di inattività, rendi persistenti i dati di sessione. Ad esempio, una plancia, un elenco della cronologia o il turno attuale.

**Per rendere persistenti i dati di sessione:**

1. In [`handleStart()`](/it/developers/backend/resources/actors/reference#lifecycle-handlers), carica i valori da [`this.storage`](/it/developers/backend/resources/actors/reference#storage) nei campi della classe.
2. Dopo ogni modifica, chiama [`this.storage.put()`](/it/developers/backend/resources/actors/reference#storage) per salvare il valore aggiornato.
3. Per reimpostare la sessione, chiama [`this.storage.delete()`](/it/developers/backend/resources/actors/reference#storage) o [`this.storage.deleteAll()`](/it/developers/backend/resources/actors/reference#storage).

L'esempio seguente carica una plancia all'avvio, la salva dopo ogni mossa e svuota lo storage quando l'ultimo client si disconnette:

```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();
  }
}
```

Per saperne di più sullo storage, consulta [storage](/it/developers/backend/resources/actors/reference#storage).

## Scrivere dati delle entità da una sessione

Quando la sessione deve creare o aggiornare record dell'app, scrivi dati delle entità. Ad esempio, un punteggio finale o un ordine completato.

**Per scrivere dati delle entità da una sessione:**

1. Valida il messaggio in arrivo prima di scrivere.
2. Leggi l'ID utente da [`conn.identity.userId`](/it/developers/backend/resources/actors/reference#connections).
3. Usa [`this.client.asServiceRole`](/it/developers/backend/resources/actors/reference#entity-access) per un accesso elevato. Scrivi con una chiave stabile, come l'ID di sessione, così un handler ripetuto aggiorna lo stesso record.

L'esempio seguente salva un punteggio finale per il client autenticato. Un salvataggio successivo per la stessa sessione aggiorna quel record:

```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);
  }
}
```

Per saperne di più sull'accesso alle entità, consulta [accesso alle entità](/it/developers/backend/resources/actors/reference#entity-access).

## Chiamare una funzione backend per operazioni con secret

Gli actor possono leggere i secret dell'app con [`secrets.get()`](/it/developers/backend/resources/actors/reference#read-secrets). Quando un handler deve eseguire un'operazione che usa un secret, come chiamare un'API esterna con una chiave API, ti consigliamo di chiamare una [funzione backend](/it/developers/backend/resources/backend-functions/overview). La funzione legge il secret e restituisce il risultato, mai il secret.

**Per chiamare una funzione backend da un actor:**

1. Crea una funzione backend che legge il secret con `secrets.get()`, esegue l'operazione e restituisce il risultato.
2. In un handler, chiama [`this.client.functions.invoke()`](/it/developers/references/sdk/docs/interfaces/functions#invoke) con il nome della funzione e i dati da inviare.
3. Usa il risultato nella tua sessione, ad esempio trasmettendolo ai client connessi.

L'esempio seguente mostra una funzione backend che legge una chiave API e restituisce una traduzione:

```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 });
}
```

L'esempio seguente chiama quella funzione da un actor e trasmette il risultato:

```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 });
  }
}
```

## Vedi anche

* [Panoramica degli actor](/it/developers/backend/resources/actors/overview): Concetti e terminologia
* [Creare un actor](/it/developers/backend/resources/actors/create-actor): File degli actor e una classe minima
* [File e codice degli actor](/it/developers/backend/resources/actors/reference): API completa della classe di backend
* [`actors deploy`](/it/developers/references/cli/commands/actors-deploy): Distribuisci gli actor locali

<Note>Questa pagina è stata tradotta con l'AI. Per le informazioni più accurate e aggiornate, consulta la [versione inglese](/). </Note>


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