Menu
Coddy logo textTech

Stream Controllers

Parte de la sección Programación Orientada a Objetos del Journey de Dart de Coddy. Lección 78 de 110.

Aunque los generadores async* son excelentes para crear flujos con datos predefinidos, a veces necesitas más control, como añadir datos a un flujo desde distintas partes de tu código. Ahí es donde entra en juego StreamController.

Un StreamController actúa como administrador de un flujo. Te proporciona un «sink» para añadir datos y un «stream» al que los oyentes pueden suscribirse:

import 'dart:async';

void main() {
  var controller = StreamController<String>();
  
  // Escuchar el stream
  controller.stream.listen((data) {
    print('Received: $data');
  });
  
  // Agregar datos a través del sink
  controller.add('Hello');
  controller.add('World');
  
  controller.close();  // Cerrar siempre al terminar
}

El método add() inserta nuevos valores en el flujo, y cualquier escucha los recibe inmediatamente. Siempre debes llamar a close() cuando hayas terminado para liberar recursos.

De forma predeterminada, un flujo solo puede tener un oyente. Para varios oyentes, usa un controlador de difusión:

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

Los StreamControllers son esenciales en la POO para construir clases orientadas a eventos, como notificar a múltiples partes de su aplicación cuando los datos cambian, manejar acciones del usuario o gestionar actualizaciones en tiempo real dentro de sus objetos.

challenge icon

Desafío

Fácil

¡Construyamos un sistema de centro de mensajes que permita que varios suscriptores reciban mensajes en tiempo real! Usarás un StreamController para gestionar el flujo de mensajes y demostrar cómo los streams de difusión permiten varios listeners.

Organizarás tu código en dos archivos:

  • message_hub.dart: Crea una clase MessageHub que gestione la distribución de mensajes mediante un StreamController. Tu centro debe:
    • Usar internamente un StreamController<String> de difusión para que varios listeners puedan suscribirse
    • Proporcionar un getter llamado messages que devuelva el stream al que los listeners puedan suscribirse
    • Tener un método broadcast(String message) que añada un mensaje al stream
    • Tener un método shutdown() que cierre el controlador
  • main.dart: Importa tu centro de mensajes y configura un escenario con varios suscriptores escuchando el mismo stream:
    • Crea una instancia de MessageHub
    • Añade un primer listener que imprima los mensajes con el formato: Subscriber A: [message]
    • Añade un segundo listener que imprima los mensajes con el formato: Subscriber B: [message]
    • Difunde tres mensajes: Hello everyone, Welcome to the hub y Goodbye
    • Apaga el centro

Recuerda importar dart:async en tu archivo del centro de mensajes para acceder a StreamController. Observa cómo ambos suscriptores reciben cada mensaje que se difunde: ¡ese es el poder de los streams de difusión!

Salida esperada:

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

Pruébalo tú mismo

import 'message_hub.dart';

void main() {
  // TODO: Crea una instancia de MessageHub
  
  // TODO: Añade el primer listener que imprima: Subscriber A: [message]
  
  // TODO: Añade el segundo listener que imprima: Subscriber B: [message]
  
  // TODO: Transmite tres mensajes:
  // - "Hello everyone"
  // - "Welcome to the hub"
  // - "Goodbye"
  
  // TODO: Cierra el hub
}
quiz iconPonte a prueba

Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.

Todas las lecciones de Programación Orientada a Objetos

Practica por tu cuenta: Compilador de Dart online