Menu
Coddy logo textTech

Controladores de Stream

Parte da seção Programação Orientada a Objetos do Journey de Dart da Coddy. Lição 78 de 110.

Embora os geradores async* sejam ótimos para criar streams com dados predefinidos, às vezes você precisa de mais controle — como adicionar dados a um stream de diferentes partes do seu código. É aí que entra StreamController.

Um StreamController atua como um gerenciador de um fluxo. Ele fornece um "sink" para adicionar dados e um "stream" ao qual os ouvintes podem se inscrever:

import 'dart:async';

void main() {
  var controller = StreamController<String>();
  
  // Escuta o stream
  controller.stream.listen((data) {
    print('Received: $data');
  });
  
  // Adiciona dados através do sink
  controller.add('Hello');
  controller.add('World');
  
  controller.close();  // Sempre feche quando terminar
}

O método add() insere novos valores no fluxo, e todos os listeners os recebem imediatamente. Você deve sempre chamar close() quando terminar para liberar os recursos.

Por padrão, um fluxo pode ter apenas um ouvinte. Para vários ouvintes, use um controlador de transmissão:

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

StreamControllers são essenciais em OOP para a construção de classes orientadas a eventos - como notificar várias partes do seu aplicativo quando os dados mudam, lidar com ações do usuário ou gerenciar atualizações em tempo real dentro dos seus objetos.

challenge icon

Desafio

Fácil

Vamos criar um sistema de central de mensagens que permite que vários assinantes recebam mensagens em tempo real! Você usará um StreamController para gerenciar o fluxo de mensagens e demonstrar como os streams de broadcast permitem vários ouvintes.

Você organizará seu código em dois arquivos:

  • message_hub.dart: crie uma classe MessageHub que gerencie a distribuição de mensagens usando um StreamController. Sua central deve:
    • Usar internamente um StreamController<String> de broadcast para que vários ouvintes possam se inscrever
    • Fornecer um getter chamado messages que retorne o stream para que os ouvintes se inscrevam
    • Ter um método broadcast(String message) que adicione uma mensagem ao stream
    • Ter um método shutdown() que feche o controlador
  • main.dart: importe sua central de mensagens e configure um cenário com vários assinantes ouvindo o mesmo stream:
    • Crie uma instância de MessageHub
    • Adicione um primeiro ouvinte que imprima as mensagens no formato: Subscriber A: [message]
    • Adicione um segundo ouvinte que imprima as mensagens no formato: Subscriber B: [message]
    • Faça o broadcast de três mensagens: Hello everyone, Welcome to the hub e Goodbye
    • Desligue a central

Lembre-se de importar dart:async no arquivo da sua central de mensagens para acessar StreamController. Observe como os dois assinantes recebem todas as mensagens que são transmitidas — esse é o poder dos streams de broadcast!

Saída 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

Experimente você mesmo

import 'message_hub.dart';

void main() {
  // TODO: Criar uma instância de MessageHub
  
  // TODO: Adicionar o primeiro listener que imprime: Subscriber A: [message]
  
  // TODO: Adicionar o segundo listener que imprime: Subscriber B: [message]
  
  // TODO: Transmitir três mensagens:
  // - "Hello everyone"
  // - "Welcome to the hub"
  // - "Goodbye"
  
  // TODO: Desligar o hub
}
quiz iconTeste seus conhecimentos

Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.

Todas as lições de Programação Orientada a Objetos

Pratique por conta própria: Compilador de Dart online