Pengenalan Stream di NodeJS 2

Jadi teman2, kalian sudah membaca tutorial sebelumnya tentang pengenalan stream?. Jika belum silahkan dibaca dulu.

Ok, jika tidak mau silahkan dilanjutkan saja bacanya -_-“.

stream illustrator

NodeJS menggunakan stream dalam mekanisme transfer data, misal disaat operasi membaca dan menulis file, operasi transfer data melalui jaringan. Selain itu NodeJS juga memiliki standard stream yaitu stdin, stdout, dan stderr.

Semua stream turunan dari EventEmitter.  Ada beberapa macam stream di Node, yaitu Read, Write, Duplex dan Transform.  Beberapa module di NodeJS sudah mengimplementasikan stream, selain itu kita juga bisa membuat api stream sendiri.

Ok, mari kita lihat contoh module di NodeJS yang sudah menggunakan stream :

var fs = require('fs');
var zlib = require('zlib');
var gzip = zlib.createGzip();

var rs = fs.createReadStream('counter.js');
var ws = fs.createWriteStream('counter.js.gz');

rs.pipe(gzip).pipe(ws)
                  .on('finish', function () { 
		        console.log('done compressing');
	           });

Script diatas melakukan kompres file dari counter.js ke counter.js.gz. Menggunakan module fs untuk membuat readable stream dan writable stream. Selain itu module zlib juga sudah mengimplementasikan stream.

Cukup menarik bukan, tapi bagaimana jika kita ingin mengimplementasikan api stream sendiri di module kita. Sekarang mari kita lihat lebih lanjut tentang stream di NodeJS

Readable Stream
readable stream adalah tempat data diproduksi, anggaplah seperti keran air. Kita bisa membuat readable stream dengan mengimplementasikan method _read(size).

Writable Stream
writable stream adalah tempat masuknya data yang berasal dari readable stream. Untuk membuat writable stream dengan mengimplementasikan method _write(chunk, enc, next).

Duplex Stream
duplex stream mempunyai kemampuan sebagai read stream maupun write stream. Untuk membuat duplex stream dengan mengimplementasikan method _write(chunk, enc, next) dan _read(size).

Transform Stream
fungsinya mirip seperti duplex stream namun lebih simple karena kita cukup mengimplementasikan _transform(chunk, enc, next).

Mari kita coba membuat studi kasus membuat api stream sendiri, implementasi dari Readable Stream, Writable Stream dan Transform Stream. Kali ini adalah kasus dari dek Azizah yg femes itu :3

Malam ini adalah malam yg sunyi dan dingin, dek Azizah sedang termenung mengenang masa lalu. Sang Kucing “Kumi” ingin menghibur dek Azizah yg sedang galau, maka si Kumi mengajak sahabatnya itu untuk menyanyi duet — cerita macam apa ini ( -_-)/|| —

Yang pertama adalah membuat module Kucing untuk Kumi, module ini mengimplementasikan readable stream. Data yang keluar adalah suara kucing semacam ‘MEOONG’, ‘MEW’, ‘MOOOW’. Buatlah file ‘kucing.js’ dan masukkan script berikut :

var Readable =  require('stream').Readable;
var util = require('util');

util.inherits(Kucing, Readable);

function Kucing(opt) {
	Readable.call(this, opt);

	this._max = 10;
	this._index = 1;
	this.lyrics = ['MEEW', 'MIAAAW', 'MEONG', 'MIIIIAAAAAW', 'MEEWWEEE', 'WOOOOW', 'MIIIIIW', 'MIAWW', 'MUAAAWW'];
	this.lyricsLength = this.lyrics.length - 1;
}

Kucing.prototype._read = function() {
	var i = this._index++; 
	var newLyrics = this.lyrics[Math.round(Math.random() * this.lyricsLength)];

	if (i > this._max) {
		this.push(null);
	} else {
		this.push(newLyrics + ' ');
	}
};

module.exports = Kucing;

Pada script diatas cukup simple yaitu memanggil class Readable kemudian membuat turunannya yaitu fungsi Kucing. Fungsi Kucing ini mengimplementasikan _read() yg isinya hanya mengambil data random dari lyrics kemudian melemparnya ke stream menggunakan push(). Yang perlu diperhatikan adalah tipe data null yg dimasukkan ke push(), yang berarti data stream sudah selesai dikirim.

Yang kedua adalah membuat module Orang untuk dek Azizah yang mendengarkan suara kucing yang kemudian berkolaborasi membentuk sebuah lagu yg berisi suara Kumi dan kalimat galau milik dek Azizah. Module Orang merupakan implementasi dari writable stream. Buatlah file ‘orang.js’ dan masukkan script berikut :

var Writable = require('stream').Writable;
var util = require('util');

util.inherits(Orang, Writable);

function Orang(opt) {
	Writable.call(this, opt);
	this.lyrics = ['Aku merindukanmu', 'Malam sendiri', 'Dimanakah dirimu sekarang', 'Sejak dirimu pergi', 'Pernahkah kau merasa', 'Semua ini sia siaa'];
	this.lyricsLength = this.lyrics.length - 1;
}

Orang.prototype._write = function(chunk, enc, next) {
	var newLyrics = this.lyrics[Math.round(Math.random() * this.lyricsLength)];
	console.log(newLyrics + ' ' + chunk.toString());
	next();
};

module.exports = Orang;

Pada script diatas kita membuat turunan dari class Writable yang kemudian membuat implementasi _write(). Isi dari _write() adalah menerima data dari Readable stream kemudian memodifikasinya dengan data dari lyrics.

Kemudian mari kita lihat hasil kolaborasi dari Kumi dan dek Azizah. Buat file ‘test.js’ yang berisi script berikut

var Kucing = require('./kucing');
var Orang = require('./orang');

var kumi = new Kucing();
var azizah = new Orang();

kumi.pipe(azizah);

Kemudian jalankan file test.js

node test.js

Hasil di console sebagai berikut :

stream1

Duetnya ternyata cukup merdu, tapi cobaan buat dek Azizah belumlah selesai disini. Anjing tetangga yang bernama “Dogi” yang merupakan musuh Kumi berusaha mengganggu duet mereka berdua. Akhirnya Dogi menjegoki mereka berdua yang sedang khusyuk berduet.

Yang ketiga adalah membuat module Anjing yang mengimplementasikan transform stream. Buatlah file ‘anjing.js’ dan diisi dengan script berikut :

var Transform = require('stream').Transform;
var util = require('util');

util.inherits(Anjing, Transform);

function Anjing(opt) {
	Transform.call(this, opt);
	this.lyrics = ['GUUK', 'RWARR', 'KAINGG', 'GRUUUK', 'AUMMMM', 'WOOOFF', 'GUUUKKK', 'KAANG', 'RRRRWRR'];
	this.lyricsLength = this.lyrics.length - 1;
}

Anjing.prototype._transform = function(chunk, enc, next) {
	var newLyrics = chunk.toString() + ' ' + this.lyrics[Math.round(Math.random() * this.lyricsLength)];
	this.push(newLyrics);
	next();
};

module.exports = Anjing;

Pada dasarnya _transform() mirip dengan _write(), hanya saja kita bisa menggunakan _push() untuk mengirim data stream.

Kemudian mari kita lihat kolaborasi rusuh mereka, kita edit script di file “test.js” menjadi seperti berikut :

var Kucing = require('./kucing');
var Orang = require('./orang');
var Anjing = require('./anjing');

var kumi = new Kucing();
var dogi = new Anjing();
var azizah = new Orang();

kumi.pipe(dogi).pipe(azizah);

Kemudian jalankan lagi file ‘test.js’ dan hasilnya sebagai berikut :

stream2

Singkat kata, dek Azizah, Kumi, dan Dogi hidup bahagia selamanya. Tamat

Wow, hasil kolaborasinya lumayan hancur ternyata. Tapi tidaklah mengapa karena tutorial ini berakhir sampai disini saja *sujud syukur.

Baiklah, tutorial diatas selo sekali bukan?.  Padahal dalam dunia nyata stream ini sangat bermanfaat dan serius -_-.

Harapannya kalian bisa memahami konsep stream dan menggunakanya demi kemaslahatan orang banyak. Untuk lebih mendalami stream di NodeJS silahkan baca2 dokumentasinya disini. Dan jika masih selo silahkan tengok Gulp yaitu streaming build system, mungkin saya akan coba bahas dilain waktu. Terima kasih

4 Replies to “Pengenalan Stream di NodeJS 2”

Leave a Reply

Your email address will not be published. Required fields are marked *