[Node.js] Stream

Vorhandenheit ·2021년 10월 28일
0

JS/Node 

목록 보기
22/63

Stream

http 트랜잭션 해부를 이해하기 위한 두번째 '스트림'입니다.

1. 스트림이란?

공식문서에서는 '스트리밍 데이터 작업을 위한 추상 인터페이스' 라고 합니다. 네! 무슨 말인지 모르겠습니다! 여러 블로그에 공통적으로 설명하는 특징은 "데이터를 쪼개서 처리한다. 큰 데이터를 처리하거나 비동기적으로 얻을 때 유리하다! "였습니다.

흔히 버퍼와 스트림을 비교해서 설명합니다. 제가 어린시절만 하더라도 '버퍼링'이라는게 있었는데 이때에는 인터넷에서 영상을 틀려고하면 영상이 다 다운이되야만 영상 재생이 가능했습니다. 그 기다리는 시간을 '버퍼링'이라고 표현했습니다.
하지만 동영상 파일이 클 경우에는 당연히 한참을 기다려야했습니다. 이에 대한 대안으로 나온게 바로 스트림입니다.
데이터를 쪼갠 뒤에 앞 부분만 다운받아 재생하는 동안, 다음 쪼갠 부분을 다운받아서 이어서 재생하게 하는 것입니다. '비동기적'방식과 똑같다는 걸 유추할 수 있을 것입니다.
이렇게 데이터를 보내는 방식(데이터의 흐름)이 바로 스트림입니다.

2. 스트림 유형


각 유형은 EventEmitter의 인스턴스입니다. (이벤트 핸들러르르 작성할 수 있습니다.)

(1) Writable : 데이터를 쓸 수 있는 스트림

A. Writable

  • fs.createReadStream 로부터 나오는 Stream 객체
  • process.stdin 표준입력을 Readable Stream으로 읽어내는 것 역시 가능
  • 서버 입장의 HTTP 요청 - 클라이언트의 요청을 읽어낼 수 있는 Stream
  • 클라이언트 입장의 HTTP 응답 - 서버로부터 돌아온 응답을 읽어낼 수 있는 Stream
http.createServer((request, reponse) => {
	response.wrtie(JSON.stringfy(reponse))
})_

여기서 response가 writable 스트림입니다.

(2) Readable : 데이터를 읽을 수 있는 스트림

A.Readable

  • fs.createReadStream 으로부터 나오는 Stream 객체
  • process.stdin 표준입력을 Readable Stream으로 읽어내는 것 역시 가능
  • 서버 입장의 HTTP 요청 - 클라이언트의 요청을 읽어낼 수 있는 Stream
  • 클라이언트 입장의 HTTP 응답 - 서버로부터 돌아온 응답을 읽어낼 수 있는 Stream
http.createServer((request, response) => {
	request.on('data', () => {})
})

여기서 request가 Readable 스트림입니다.

두 가지 모드가 있습니다.

  • paused : 읽기 기본 패턴은 새로운 데이터를 읽을 준비가 되었다는 신호인 readable 이벤트에 listener를 등록하는 것, readable 리스너에서 독점적으로 읽을 수 있음
    stream.read() 메서드를 호출하여 스트림에서 데이터 청크를 읽게 만들어야함

  • flowing : data 이벤트에 리스너를 등록하는 것, read()를 사용하여 꺼내지 않고 데이터가 도착하자마자 해당 리스너에게 전달
    자동으로 데이터가 읽힘

(3) Duplex : Readable & Writable 스트림

A. Duplex

  • TCP sockets : 네트워크를 통해 주고받음
  • zlib streams : 압축 알고리즘 적용된 스트림
  • crypto streams : 암호화 알고리즘 모듈

(4) Transfrom : 데이터를 쓰고 읽을 때 데이터를 수정하거나 변환 할 수 있는 Duplex 스트림

A. Transform

  • zlib streams
  • crypto streams

3. Stream Event

(1) Writiable EVENT

  • close : close 이벤트는 스트림이나 리소스가 닫혔을 때 발생

  • drain : response.write(chunk)가 false를 리턴한 상황에, write 작업이 다시 실행될 수 있는 상황이 되면 drain 이벤트가 발생하게 됩니다.

  • error : 데이터 쓰기 중 오류가 발생하면 이벤트가 발생합니다.

  • finish : stream.end() 메서드가 호출된 뒤에 발생하는 이벤트

  • pipe : 중요합니다! stream.pipe() 가 readable stream에서 호출되었을 때 발생하는 이벤트, pipe도착지로 writable을 세팅해줘야합니다.

  • write : body를 작성

writable.write(chunk, [,encoding][,callback])

  • chunk : 쓰게할 데이터, object mode가 아니면 chunk는 무조건 string, Buffer, Unit8Array이어야만 합니다.
  • encoding : 인코딩 형식, chunk가 string 이라면 'utf8'이 디폴트값
  • callback : 데이터가 쓰여졌을 떄에 콜백

(2) Readable Event

  • close : close 이벤트는 스트림 및 기본 리소스가 닫힐 때 발생합니다. 더 이상 이벤트가 발생하지 않으며 더 이상 어떠한 계산이 발생하지 않게 됩니다.

  • pause : stream.pause() 가 호출되었을 때, readableFlowing이 false가 아닐 때 발생

  • pipe

    readable.pipe(destination[,options])

redable.pipe() 메서드는 readable에 writiable을 붙여줍니다. flowing mode로 변경시키고 writable로 데이터를 보냅니다

const fs = require('fs');
const readable = getReadableStreamSomehow()
const writable = fs.createWriteStream('file.txt');
redable.pipe(writable) // 모든 readable데이터는 'file.txt'로 가게됩니다.

출처

https://vanayun.netlify.app/til/2019-05-24-node_09/
https://woooseogi.tistory.com/21
https://psyhm.tistory.com/26
https://jonyo.tistory.com/141
https://velog.io/@moongq/Stream-Nodejs

profile
읽고 기록하고 고민하고 사용하고 개발하자!

0개의 댓글