Node.js でメモリ上のデータから stream を作る
fs.createReadStream()
等でストリームを作るのではなく、メモリ上のデータでストリームを開始する方法です。
但し、node.js のストリームの触り始めの人が書いているので話半分で。
サンプルコードの概要
- サンプルは Web サーバのレスポンスを想定しています。
- 返信文書(データ)の用意までに1000ミリ秒を要し、このデータはメモリ上に用意されます。
- しかし、他の Web ページの配信にも使用しているファイルストリームのトランスフォーマー(common/transformer.js) を共有したいので、メモリ上のデータをストリームに変換する、というシナリオです。
MemoryReadableStream クラス
まずは MemoryReadableStream クラスを定義します。
データの準備に時間がかかるのでコンストラクタの中で pause()
しています。
データが用意出来たら、再開 resume()
する時に、引数に全てのデータを渡します。このデータに続いてストリームの終わりを示す null
が送られます。
const stream = require('stream');
class MemoryReadableStream extends stream.Readable{
constructor(){
super();
this._data = '';
this.pause();
}
_read(n){
this.push(this._data);
}
resume(data){
if(this.paused && data && this._data !== null){
this.push(data);
this._data = null;
};
super.resume();
}
};
1秒後にウェブページを返す Web サーバの例
続いて MemoryReadableStream
インスタンスを作って、transformer を pipe()
します。
1秒の時間を要する処理の後に、出来あがったデータを引数に resume(data)
を呼びます。
このデータは transformer での処理を経て、完全な HTML 文書となってウェブブラウザに送信されます。
const transformer = require('common/transformer.js');
require('http').createServer(
(request, response) => {
const stream = new MemoryReadableStream();
stream.pipe(transformer).pipe(response);
setTimeout(
function(){
if (!stream.ended) stream.resume('...data...');
}, 1000
);
}
).listen(8080);