Application/Flutter

[Flutter] 스트림(Stream) 통신하기

유제필 2022. 11. 21. 22:36

스트림(Stream) 통신이란

애플리케이션을 개발할 때 데이터를 순서대로 주고 받아야 할 경우가 있는데, 이와 같은 상황에서 데이터를 받을 순서를 보장할 때 스트림을 이용한다.

 

중간에 와이파이가 끊어져 데이터를 받지 못하거나 특정 API 호출이 늦어져 순서가 달라지면 애플리케이션이 원하는 흐름대로 동작하지 않는다.

 

이런 경우에 스트림을 이용하는데, 스트림은 처음에 넣은 데이터가 꺼낼 때도 가장 먼저 나오는 데이터 구조로 볼 수 있다.

따라서 스트림을 이용하면 데이터를 차례대로 주고받는 코드를 작성할 수 있다.

 

아래 예제는 스트림 통신의 예제이다.

 

import 'dart:io';
import 'dart:async';

Future<int> sumStream(Stream<int> stream) async {
	var sum = 0;
	
	await for (var value in stream) {
		print('sumStream : $value');
		
		sum += value;
	}
	
	return sum;
}

Stream<int> countStream(int to) async* {
	for (int i = 1; i <= to; i++) {
		print('countStream : $i');
		yield i;
	}
}
 
void main() async {
	var stream = countStream(10);
	var sum = await sumStream(stream);
	
	print(sum);
}

 

실행 결과

countStream : 1
sumStream : 1
countStream : 2
sumStream : 2
countStream : 3
sumStream : 3
countStream : 4
sumStream : 4
countStream : 5
sumStream : 5
countStream : 6
sumStream : 6
countStream : 7
sumStream : 7
countStream : 8
sumStream : 8
countStream : 9
sumStream : 9
countStream : 10
sumStream : 10
55

 

main() 함수에서 먼저 countStream() 함수에 10을 담아 호출한다.

 

countStream() 함수 안에서 yield 키워드와 async* 키워드를 이용해 비동기 함수로 만들었다.

 

async* 키워드는 앞으로 yield를 이용해 지속적으로 데이터를 전달하겠다는 의미이다.

이 예제에서 yield는 int형 i를 반환하는데, return은 한 번 반환하면 함수가 끝나지만 yield는 반환 후에도 계속 함수를 유지한다.

 

이후 for문을 이용해 1부터 매개변수로 받은 to로 전달받은 숫자까지 반복한다.

 

이렇게 받은 yield값을 인자로 sumStream() 함수를 호출하면 이 값이 전달될 때마다 sum 변수에 누적해서 반환해 준다.

그리고 main() 함수에서 이 값을 받아서 출력하면 55가 나온다.

 

이 예제와 같이 스트림을 이용하면 데이터를 차례대로 받아서 처리할 수 있다.

 

 

또한 Stream 클래스와 then() 함수를 이용해도 스트림 코드를 작성할 수 있다.

import 'dart:io';
import 'dart:async';
 
void main() {
	var stream = Stream.fromIterable([1, 2, 3, 4, 5]);
	
	stream.first.then((value) => print('first : $value'));
	stream.last.then((value) => print('last : $value'));
	stream.isEmpty.then((value) => print('isEmpty : $value'));
	stream.length.then((value) => print('length : $value'));
}

 

하지만 이렇게 Stream 클래스를 이용하여 사용할 때 주의할 점이 있다.

 

스트림을 통해 데이터를 사용하면 데이터는 사라지기 때문에 처음 then 함수로 사용한 스트림만 사용할 수 있고, 나머지 스트림은 사용할 수 없다.

 

따라서 위 4가지의 출력하는 예제 중 1가지의 출력만 해야 성공적으로 코드가 동작한다.

 

스트림은 실시간 서버를 살펴보다가 서버에서 데이터가 변경되면 화면을 새로 고침하지 않더라도 자동으로 변경된 데이터가 반영되어야 할 때 사용할 수 있는 유용한 클래스이다.