Menu
Coddy logo textTech

Controller degli stream

Fa parte della sezione Programmazione orientata agli oggetti del percorso Dart di Coddy. Lezione 78 di 110.

Sebbene i generatori async* siano ottimi per creare flussi con dati predefiniti, a volte hai bisogno di più controllo, ad esempio per aggiungere dati a un flusso da diverse parti del tuo codice. È qui che entra in gioco StreamController.

Un StreamController funge da gestore per uno stream. Ti fornisce un "sink" a cui aggiungere dati e uno "stream" a cui gli ascoltatori possono iscriversi:

import 'dart:async';

void main() {
  var controller = StreamController<String>();
  
  // Ascolta il flusso
  controller.stream.listen((data) {
    print('Received: $data');
  });
  
  // Aggiungi dati tramite il sink
  controller.add('Hello');
  controller.add('World');
  
  controller.close();  // Chiudi sempre quando hai finito
}

Il metodo add() inserisce nuovi valori nello stream e tutti i listener li ricevono immediatamente. Dovresti sempre chiamare close() quando hai finito, per liberare le risorse.

Per impostazione predefinita, uno stream può avere un solo ascoltatore. Per più ascoltatori, usa un controller broadcast:

import 'dart:async';

void main() {
  var controller = StreamController<int>.broadcast();
  
  controller.stream.listen((n) => print('Listener 1: $n'));
  controller.stream.listen((n) => print('Listener 2: $n'));
  
  controller.add(42);
  controller.close();
}

Gli StreamController sono essenziali nella OOP per creare classi basate sugli eventi, ad esempio per notificare più parti della tua app quando i dati cambiano, gestire le azioni degli utenti o amministrare aggiornamenti in tempo reale all'interno dei tuoi oggetti.

challenge icon

Sfida

Facile

Creiamo un sistema di hub di messaggi che consenta a più sottoscrittori di ricevere messaggi in tempo reale! Userai un StreamController per gestire il flusso dei messaggi e mostrare come gli stream broadcast consentano a più listener di ascoltare.

Organizzerai il codice in due file:

  • message_hub.dart: crea una classe MessageHub che gestisca la distribuzione dei messaggi usando uno StreamController. Il tuo hub dovrebbe:
    • Usare internamente un StreamController<String> broadcast, in modo che più listener possano sottoscriversi
    • Fornire un getter chiamato messages che restituisca lo stream a cui i listener possono sottoscriversi
    • Avere un metodo broadcast(String message) che aggiunga un messaggio allo stream
    • Avere un metodo shutdown() che chiuda il controller
  • main.dart: importa il tuo hub di messaggi e imposta uno scenario con più sottoscrittori in ascolto sullo stesso stream:
    • Crea un'istanza di MessageHub
    • Aggiungi un primo listener che stampi i messaggi nel formato: Subscriber A: [message]
    • Aggiungi un secondo listener che stampi i messaggi nel formato: Subscriber B: [message]
    • Trasmetti tre messaggi: Hello everyone, Welcome to the hub e Goodbye
    • Arresta l'hub

Ricorda di importare dart:async nel file dell'hub di messaggi per accedere a StreamController. Nota come entrambi i sottoscrittori ricevano ogni messaggio trasmesso: questa è la potenza degli stream broadcast!

Output previsto:

Subscriber A: Hello everyone
Subscriber B: Hello everyone
Subscriber A: Welcome to the hub
Subscriber B: Welcome to the hub
Subscriber A: Goodbye
Subscriber B: Goodbye

Provalo tu

import 'message_hub.dart';

void main() {
  // TODO: Crea un'istanza di MessageHub
  
  // TODO: Aggiungi il primo listener che stampa: Subscriber A: [message]
  
  // TODO: Aggiungi il secondo listener che stampa: Subscriber B: [message]
  
  // TODO: Trasmetti tre messaggi:
  // - "Hello everyone"
  // - "Welcome to the hub"
  // - "Goodbye"
  
  // TODO: Chiudi l'hub
}
quiz iconMettiti alla prova

Questa lezione include un breve quiz. Inizia la lezione per rispondere e tenere traccia dei tuoi progressi.

Tutte le lezioni di Programmazione orientata agli oggetti

Esercitati da solo: Compilatore Dart online