Foggy day

[Dart] stream 사용법 -3, StreamController broadcast(multiple listen) 본문

Flutter/Dart 문법

[Dart] stream 사용법 -3, StreamController broadcast(multiple listen)

jinhan38 2023. 7. 13. 23:14

 

이번 포스팅에서는 StreamController의 broadcast에 대해 알아보겠습니다.

 

stream 사용법 -2에서는 single listen을 사용했었습니다. 리스너를 한개만 붙여서 사용할 수 있었습니다. 

StreamController에는 여러개의 broadcast를 이용해 여러개의 listener를 사용할 수 있습니다. 

 

 

 

 

1. StreamController.broadcast생성

2. Listener 추가 

3. add, addStream

4. onListen, onResume, onPause, onCancel

5. 리스너 여러개 추가

5. close

 

 

 

 

실행 영상

 

 

 

 

1. StreamController 생성

여러개의 리스너를 사용하고 싶다면 생성할 때 broadcast 생성자를 사용해야 합니다.

  final streamController = StreamController.broadcast(
    onListen: () {
      print('onListen');
    },
    onCancel: () {
      print('onCancel');
    },
  );

 

 

 

 

2. Listener 추가 

initState 함수에서 listen과 onDone 함수를 구현했습니다. 이제 stream에 데이터를 보내면 listen 함수에 타게됩니다. 

  int value = 0;
  
  
  @override
  void initState() {
    streamController.stream.listen((event) {
      print('listen : $event');
      if (mounted) {
        setState(() {
          value += event as int;
        });
      }
    }).onDone(() {
      // streamController.close()를 호출하면 진입
      print('done : $value');
    });
    super.initState();
  }

 

 

 

 

3. Add

stream에 데이터를 보내는 것은 single streamcontroller와 동일합니다.

- 단일 데이터 전달 

streamController.add(1)

 

- 스트림으로 전달 

  streamController.addStream(countStream(5))

......

  Stream<int> countStream(int to) async* {
    for (int i = 1; i <= to; i++) {
      await Future.delayed(const Duration(milliseconds: 300));
      yield i;
    }
  }

 

 

 

 

4. onListen, onResume, onPause, onCancel

StreamController.broadcast에서는 onResumer과 onPause 함수는 사용 불가능합니다. 만약 호출했을 때 아래와 같은 오류 메세지를 볼 수 있습니다. 

Unsupported operation: Broadcast stream controllers do not support pause callbacks

onListen과 onCancel은 호출 가능합니다.

streamController.onListen?.call()
streamController.onCancel?.call()

 

 

 

 

4. 리스너 여러개 추가 

다른 화면에서 두 개의 리스너를 추가해보겠습니다.

여러개의 화면이 있더라도 listener를 붙여놓은 화면이 살아있다면 데이터를 받을 수 있습니다.

 

- 두번째 화면에서 리스너 추가 

  int value = 0;
  
  @override
  void initState() {
    widget.streamController.stream.listen((event) {
      print('listen second : $event');
      if (mounted) {
        setState(() {
          value += event as int;
        });
      }
    }).onDone(() {
      print('done : $value');
    });
    super.initState();
  }

 

- 세 번째 화면에서 리스너 추가 

  int value = 0;

  @override
  void initState() {
    widget.streamController.stream.listen((event) {
      print('listen third : $event');
      if (mounted) {
        setState(() {
          value += event as int;
        });
      }
    }).onDone(() {
      print('done : $value');
    });
    super.initState();
  }

 

 

 

 

7. Close

close는 말 그대로 stream을 닫는 함수입니다. close를 호출한 후에 add를 한다면 오류가 발생합니다.

  @override
  void dispose() {
    streamController.close();
    super.dispose();
  }

 

 

 

 

 

Full code

코드가 길어져서 파일로 첨부했습니다. import에서 상대 경로로 추가해놨으니 같은 폴더에 넣고 사용하시면 됩니다.

 

stream_controller_screen.dart
0.01MB
stream_second_screen.dart
0.00MB
stream_third_screen.dart
0.00MB