Yups kali ini kita akan mencoba membuat sebuah aplikasi chat :D dengan menggunakan teknologi WebSocket. Apa itu WebSocket ?
WebSocket merupakan protokol yang digunakan untuk komunikasi dua arah. Berbeda dengan AJAX [Asynchronous JavaScript and XMLHTTP] yang hanya menggunakan komunikasi satu arah.
Pada AJAX, server menunggu request dari client sehingga jika client tidak mengirim request maka server tidak akan mengembalikan response. Berbeda dengan WebSocket, WebSocket dapat mengirim response ke client meskipun client tidak mengirim request. Penggunaan WebSocket sangat disarankan di beberapa tempat seperti pada aplikasi chat, aplikasi monitoring naik turun saham sebuah perusahaan, aplikasi monitoring naik turun kurs dan lain sebagainya. Dengan menggunakan komunikasi dua arah sehingga memungkinkan WebSocket menjadikan sebuah aplikasi berbasis realtime. Berikut adalah perbandingan sequence diagram pada AJAX dan WebSocket.
Sebelum adanya WebSocket terdapat beberapa teknik untuk membuat aplikasi realtime yaitu.
Pooling : Ini merupakan teknik yang sangat lama, dimana client setiap N [dalam angka] menit akan melakukan request secara berkala, sehingga apabila ada perubahan pada server, maka client akan ikut berubah akan tetapi disini terdapat kekurangan yaitu beban server akan semakin besar dikarenakan setiap N [dalam angkan] menit akan melakukan request ke server dan bayangkan jika terdapat ribuan client.
Piggyback : Teknik ini akan mengembalikan sebuah response perubahan jika si client melakukan request ke server, dan perubahan ini dikirim melalui response, terdapat kelamahan juga yaitu apabila si client tidak melakukan request maka perubahan pun tidak akan terjadi.
Reverse Ajax / Comet/ Long Pooling : merupakan teknik yang efisien yaitu client melakukan request ke server, server tidak akan langsung mengembalikan response akan tetapi server akan membuka request dalam waktu tertentu, jika sudah pada waktunya, server akan mengembalikan response ke semua client. Teknik ini bisa realtime akan tetapi membutuhkan waktu karena server membuka request dalam waktu tertentu.
Oke dari sekian teknik, akhirnya kita menggunakan teknik WebSocket dikarenakan beberapa alasan, diantaranya WebSocket memungkinkan komunikasi dua arah, teknologi Html 5 telah mendukung WebSocket dan lain sebagainya.
Pada tutorial ini, kita akan membangun sebuah aplikasi chat dengan menggunakan node js. Mengapa dengan node js ? dikarenakan node js mendukung teknologi I/O Non Blocking sehingga mempermudah kita dalam mengembangkan aplikasi yang bersifat realtime.
Berikut tahapan yang akan kita lakukan.
- Setup Kebutuhan Server
- Setup Kebutuhan Client
- Membuat Server WebSocket Dengan Socket.IO
- Membuat Client WebSocket Dengan Socket.IO Dan Material Design
- Uji Coba Aplikasi Chat
- Deploy Aplikasi ke Heroku
Setup Kebutuhan Server
Seperti biasa, buat sebuah folder dengan nama
bower install bootstrap-material-design bootstrap socket.io-client --save
0 kemudian masuk ke folder tersebut dengan terminal. Jalankan perintah bower install bootstrap-material-design bootstrap socket.io-client --save
1 lalu input data anda sesuai dengan yang diminta. Kita membutuhkan beberapa library dan framework untuk membuat websocket, maka jalankan perintah berikut.npm install express jade socket.io --save
Setup Kebutuhan Client
Jalankan perintah
bower install bootstrap-material-design bootstrap socket.io-client --save
2, sama seperti bower install bootstrap-material-design bootstrap socket.io-client --save
1 input data sesuai dengan yang diminta. Pada tutorial ini, kita akan menggunakan material design, maka memerlukan beberapa library. Jalankn perintah berikut.bower install bootstrap-material-design bootstrap socket.io-client --save
Membuat Server WebSocket Dengan Socket.IO
Buatlah sebuah file
bower install bootstrap-material-design bootstrap socket.io-client --save
4 di dalam root folder project. Berikut adalah codingan untuk servernya.'use strict';
var app = require['express'][];
var http = require['http'].Server[app];
var io = require['socket.io'][http];
var path = require['path'];
app.set['port', process.env.PORT || 3000];
app.set['views', path.join[__dirname, 'views']];
app.set['view engine', 'jade'];
app.use[require['express'].static[path.join[__dirname, 'public']]];
app.use[require['express'].static[path.join[__dirname, 'bower_components']]];
app.get['/', function[req, res] {
return res.render['index'];
}];
io.on['connection', function[socket] {
socket.on['chat:pesan', function[pesan] {
io.emit['chat:pesan', pesan];
}];
}];
http.listen[app.get['port'], function[] {
console.log['Server jalan di port ' + app.get['port']];
}];
Berikut penjelasan dari codingan diatas :
5 berfungsi untuk mendeklarasikan variabel untuk framework express jsbower install bootstrap-material-design bootstrap socket.io-client --save
6 berfungsi untuk membuat serverbower install bootstrap-material-design bootstrap socket.io-client --save
7 berfungsi untuk membuat server dengan teknologi websocketbower install bootstrap-material-design bootstrap socket.io-client --save
8 berfungsi sebagai path dari aplikasibower install bootstrap-material-design bootstrap socket.io-client --save
9 berfungsi untuk deklarasi port dari aplikasibower install bootstrap-material-design bootstrap socket.io-client --save
0 berfungsi untuk deklarasikan folder view / halaman html'use strict'; var app = require['express'][]; var http = require['http'].Server[app]; var io = require['socket.io'][http]; var path = require['path']; app.set['port', process.env.PORT || 3000]; app.set['views', path.join[__dirname, 'views']]; app.set['view engine', 'jade']; app.use[require['express'].static[path.join[__dirname, 'public']]]; app.use[require['express'].static[path.join[__dirname, 'bower_components']]]; app.get['/', function[req, res] { return res.render['index']; }]; io.on['connection', function[socket] { socket.on['chat:pesan', function[pesan] { io.emit['chat:pesan', pesan]; }]; }]; http.listen[app.get['port'], function[] { console.log['Server jalan di port ' + app.get['port']]; }];
1 berfungsi untuk mendeklarasikan bahwa kita menggunakan template engine Jade'use strict'; var app = require['express'][]; var http = require['http'].Server[app]; var io = require['socket.io'][http]; var path = require['path']; app.set['port', process.env.PORT || 3000]; app.set['views', path.join[__dirname, 'views']]; app.set['view engine', 'jade']; app.use[require['express'].static[path.join[__dirname, 'public']]]; app.use[require['express'].static[path.join[__dirname, 'bower_components']]]; app.get['/', function[req, res] { return res.render['index']; }]; io.on['connection', function[socket] { socket.on['chat:pesan', function[pesan] { io.emit['chat:pesan', pesan]; }]; }]; http.listen[app.get['port'], function[] { console.log['Server jalan di port ' + app.get['port']]; }];
2 berfungsi untuk melakukan render terhadap file index.jade, ini berfungsi sebagai root halaman dari aplikasi'use strict'; var app = require['express'][]; var http = require['http'].Server[app]; var io = require['socket.io'][http]; var path = require['path']; app.set['port', process.env.PORT || 3000]; app.set['views', path.join[__dirname, 'views']]; app.set['view engine', 'jade']; app.use[require['express'].static[path.join[__dirname, 'public']]]; app.use[require['express'].static[path.join[__dirname, 'bower_components']]]; app.get['/', function[req, res] { return res.render['index']; }]; io.on['connection', function[socket] { socket.on['chat:pesan', function[pesan] { io.emit['chat:pesan', pesan]; }]; }]; http.listen[app.get['port'], function[] { console.log['Server jalan di port ' + app.get['port']]; }];
3 berfungsi untuk inisialisasi koneksi dengan websocket'use strict'; var app = require['express'][]; var http = require['http'].Server[app]; var io = require['socket.io'][http]; var path = require['path']; app.set['port', process.env.PORT || 3000]; app.set['views', path.join[__dirname, 'views']]; app.set['view engine', 'jade']; app.use[require['express'].static[path.join[__dirname, 'public']]]; app.use[require['express'].static[path.join[__dirname, 'bower_components']]]; app.get['/', function[req, res] { return res.render['index']; }]; io.on['connection', function[socket] { socket.on['chat:pesan', function[pesan] { io.emit['chat:pesan', pesan]; }]; }]; http.listen[app.get['port'], function[] { console.log['Server jalan di port ' + app.get['port']]; }];
4 function ini menunggu event sebuah request dari client, sedangkan'use strict'; var app = require['express'][]; var http = require['http'].Server[app]; var io = require['socket.io'][http]; var path = require['path']; app.set['port', process.env.PORT || 3000]; app.set['views', path.join[__dirname, 'views']]; app.set['view engine', 'jade']; app.use[require['express'].static[path.join[__dirname, 'public']]]; app.use[require['express'].static[path.join[__dirname, 'bower_components']]]; app.get['/', function[req, res] { return res.render['index']; }]; io.on['connection', function[socket] { socket.on['chat:pesan', function[pesan] { io.emit['chat:pesan', pesan]; }]; }]; http.listen[app.get['port'], function[] { console.log['Server jalan di port ' + app.get['port']]; }];
5 merupakan perintah socket yang akan dikirim dari client, jika perintah sama maka perintah yang di dalam function ini akan dijalankan.'use strict'; var app = require['express'][]; var http = require['http'].Server[app]; var io = require['socket.io'][http]; var path = require['path']; app.set['port', process.env.PORT || 3000]; app.set['views', path.join[__dirname, 'views']]; app.set['view engine', 'jade']; app.use[require['express'].static[path.join[__dirname, 'public']]]; app.use[require['express'].static[path.join[__dirname, 'bower_components']]]; app.get['/', function[req, res] { return res.render['index']; }]; io.on['connection', function[socket] { socket.on['chat:pesan', function[pesan] { io.emit['chat:pesan', pesan]; }]; }]; http.listen[app.get['port'], function[] { console.log['Server jalan di port ' + app.get['port']]; }];
6 yang merupakan parameter dari function diatas berfungsi sebagai data yang dikirim dari client, data dapat berupa object atau array dalam format JSON.'use strict'; var app = require['express'][]; var http = require['http'].Server[app]; var io = require['socket.io'][http]; var path = require['path']; app.set['port', process.env.PORT || 3000]; app.set['views', path.join[__dirname, 'views']]; app.set['view engine', 'jade']; app.use[require['express'].static[path.join[__dirname, 'public']]]; app.use[require['express'].static[path.join[__dirname, 'bower_components']]]; app.get['/', function[req, res] { return res.render['index']; }]; io.on['connection', function[socket] { socket.on['chat:pesan', function[pesan] { io.emit['chat:pesan', pesan]; }]; }]; http.listen[app.get['port'], function[] { console.log['Server jalan di port ' + app.get['port']]; }];
7 berfungsi untuk memberikan response ke seluruh client, seperti pengertian diatas, jika client tidak melakukan request, server tetap dapat memberikan response ke client. Nah disini hanya 1 client yang melakukan request maka seluruh client nantinya akan mendapatkan response agar dapat yang diterima antara 1 client dengan clientnya sama.'use strict'; var app = require['express'][]; var http = require['http'].Server[app]; var io = require['socket.io'][http]; var path = require['path']; app.set['port', process.env.PORT || 3000]; app.set['views', path.join[__dirname, 'views']]; app.set['view engine', 'jade']; app.use[require['express'].static[path.join[__dirname, 'public']]]; app.use[require['express'].static[path.join[__dirname, 'bower_components']]]; app.get['/', function[req, res] { return res.render['index']; }]; io.on['connection', function[socket] { socket.on['chat:pesan', function[pesan] { io.emit['chat:pesan', pesan]; }]; }]; http.listen[app.get['port'], function[] { console.log['Server jalan di port ' + app.get['port']]; }];
8 berfungsi untuk menjalankan server.'use strict'; var app = require['express'][]; var http = require['http'].Server[app]; var io = require['socket.io'][http]; var path = require['path']; app.set['port', process.env.PORT || 3000]; app.set['views', path.join[__dirname, 'views']]; app.set['view engine', 'jade']; app.use[require['express'].static[path.join[__dirname, 'public']]]; app.use[require['express'].static[path.join[__dirname, 'bower_components']]]; app.get['/', function[req, res] { return res.render['index']; }]; io.on['connection', function[socket] { socket.on['chat:pesan', function[pesan] { io.emit['chat:pesan', pesan]; }]; }]; http.listen[app.get['port'], function[] { console.log['Server jalan di port ' + app.get['port']]; }];
Panjang juga penjelasannya :D , sekarang kita mulai coding untuk bagian clientnya.
Membuat Client WebSocket Dengan Socket.IO Dan Material Design
Untuk client, kali ini kita akan gunakan material design, loh knp gx pakai bootstrap aja ? alasannya penulis pengen nyobain material design :P . Bosen kan kalau terus - terusan pakai bootstrap, sekali - kali pakai material design biar bagus tampilannya. Oke silahkan buat sebuah folder views di dalam root folder project. buat file
'use strict';
var app = require['express'][];
var http = require['http'].Server[app];
var io = require['socket.io'][http];
var path = require['path'];
app.set['port', process.env.PORT || 3000];
app.set['views', path.join[__dirname, 'views']];
app.set['view engine', 'jade'];
app.use[require['express'].static[path.join[__dirname, 'public']]];
app.use[require['express'].static[path.join[__dirname, 'bower_components']]];
app.get['/', function[req, res] {
return res.render['index'];
}];
io.on['connection', function[socket] {
socket.on['chat:pesan', function[pesan] {
io.emit['chat:pesan', pesan];
}];
}];
http.listen[app.get['port'], function[] {
console.log['Server jalan di port ' + app.get['port']];
}];
9 di dalam folder views, 'use strict';
var app = require['express'][];
var http = require['http'].Server[app];
var io = require['socket.io'][http];
var path = require['path'];
app.set['port', process.env.PORT || 3000];
app.set['views', path.join[__dirname, 'views']];
app.set['view engine', 'jade'];
app.use[require['express'].static[path.join[__dirname, 'public']]];
app.use[require['express'].static[path.join[__dirname, 'bower_components']]];
app.get['/', function[req, res] {
return res.render['index'];
}];
io.on['connection', function[socket] {
socket.on['chat:pesan', function[pesan] {
io.emit['chat:pesan', pesan];
}];
}];
http.listen[app.get['port'], function[] {
console.log['Server jalan di port ' + app.get['port']];
}];
9 berfungsi sebagai layout utama sehingga kita akan lakukan import js, css, img dan lain - lain disini. Berikut kodingannya.doctype html
html[lang='en']
head
meta[charset='utf-8']
meta[name='viewport', content='width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no']
meta[name='description', content='Belajar WebSocket']
meta[name='keywords', content='keywords']
meta[name='author', content='Rizki Mufrizal']
meta[name="robots", content="index, follow"]
block title
title Default title
//- ----- CSS Files ----- //
link[rel='stylesheet', href='/bootstrap/dist/css/bootstrap.min.css']
link[rel='stylesheet', href='/bootstrap-material-design/dist/css/material.min.css']
body
block content
//- ----- JS Files ----- //
script[type='text/javascript', src='/jquery/dist/jquery.min.js']
script[type='text/javascript', src='/socket.io-client/socket.io.js']
script[type='text/javascript', src='/bootstrap/dist/js/bootstrap.min.js']
script[type='text/javascript', src='/bootstrap-material-design/dist/js/material.min.js']
script[type='text/javascript', src='/scripts/BelajarWebSocket.js']
Sama seperti html biasa, bedanya disini kita menggunakan template engine jade sehingga tidak perlu tag penutup. Oke selanjutnya buat file
doctype html
html[lang='en']
head
meta[charset='utf-8']
meta[name='viewport', content='width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no']
meta[name='description', content='Belajar WebSocket']
meta[name='keywords', content='keywords']
meta[name='author', content='Rizki Mufrizal']
meta[name="robots", content="index, follow"]
block title
title Default title
//- ----- CSS Files ----- //
link[rel='stylesheet', href='/bootstrap/dist/css/bootstrap.min.css']
link[rel='stylesheet', href='/bootstrap-material-design/dist/css/material.min.css']
body
block content
//- ----- JS Files ----- //
script[type='text/javascript', src='/jquery/dist/jquery.min.js']
script[type='text/javascript', src='/socket.io-client/socket.io.js']
script[type='text/javascript', src='/bootstrap/dist/js/bootstrap.min.js']
script[type='text/javascript', src='/bootstrap-material-design/dist/js/material.min.js']
script[type='text/javascript', src='/scripts/BelajarWebSocket.js']
1 di dalam folder doctype html
html[lang='en']
head
meta[charset='utf-8']
meta[name='viewport', content='width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no']
meta[name='description', content='Belajar WebSocket']
meta[name='keywords', content='keywords']
meta[name='author', content='Rizki Mufrizal']
meta[name="robots", content="index, follow"]
block title
title Default title
//- ----- CSS Files ----- //
link[rel='stylesheet', href='/bootstrap/dist/css/bootstrap.min.css']
link[rel='stylesheet', href='/bootstrap-material-design/dist/css/material.min.css']
body
block content
//- ----- JS Files ----- //
script[type='text/javascript', src='/jquery/dist/jquery.min.js']
script[type='text/javascript', src='/socket.io-client/socket.io.js']
script[type='text/javascript', src='/bootstrap/dist/js/bootstrap.min.js']
script[type='text/javascript', src='/bootstrap-material-design/dist/js/material.min.js']
script[type='text/javascript', src='/scripts/BelajarWebSocket.js']
2, file doctype html
html[lang='en']
head
meta[charset='utf-8']
meta[name='viewport', content='width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no']
meta[name='description', content='Belajar WebSocket']
meta[name='keywords', content='keywords']
meta[name='author', content='Rizki Mufrizal']
meta[name="robots", content="index, follow"]
block title
title Default title
//- ----- CSS Files ----- //
link[rel='stylesheet', href='/bootstrap/dist/css/bootstrap.min.css']
link[rel='stylesheet', href='/bootstrap-material-design/dist/css/material.min.css']
body
block content
//- ----- JS Files ----- //
script[type='text/javascript', src='/jquery/dist/jquery.min.js']
script[type='text/javascript', src='/socket.io-client/socket.io.js']
script[type='text/javascript', src='/bootstrap/dist/js/bootstrap.min.js']
script[type='text/javascript', src='/bootstrap-material-design/dist/js/material.min.js']
script[type='text/javascript', src='/scripts/BelajarWebSocket.js']
1 nantinya akan berfungsi sebagai root page. Berikut kodingannya.extends ./layout.jade
block title
title Belajar WebSocket
block content
div.container
div.row
div.col-xs-5.col-md-3
div.col-xs-5.col-md-6
div.panel.panel-primary
div.panel-heading
h3.panel-title Aplikasi Chat
div.panel-body
ul[id="listPesan"]
div.panel-footer
div.form-group
input[id="nama", type="text", placeholder="Masukkan Nama Anda"].form-control.floating-label
div.form-group
textarea[id="pesan", placeholder="Masukkan Pesan Anda"].form-control.floating-label
button[id="kirim", type="button"].btn.btn-primary.btn-fab.btn-raised.mdi-content-send
Teryata tidak hanya java yang bisa menggunakan extend, template engine juga bisa :D secara otomatis file
'use strict';
var app = require['express'][];
var http = require['http'].Server[app];
var io = require['socket.io'][http];
var path = require['path'];
app.set['port', process.env.PORT || 3000];
app.set['views', path.join[__dirname, 'views']];
app.set['view engine', 'jade'];
app.use[require['express'].static[path.join[__dirname, 'public']]];
app.use[require['express'].static[path.join[__dirname, 'bower_components']]];
app.get['/', function[req, res] {
return res.render['index'];
}];
io.on['connection', function[socket] {
socket.on['chat:pesan', function[pesan] {
io.emit['chat:pesan', pesan];
}];
}];
http.listen[app.get['port'], function[] {
console.log['Server jalan di port ' + app.get['port']];
}];
9 akan di include di dalam file doctype html
html[lang='en']
head
meta[charset='utf-8']
meta[name='viewport', content='width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no']
meta[name='description', content='Belajar WebSocket']
meta[name='keywords', content='keywords']
meta[name='author', content='Rizki Mufrizal']
meta[name="robots", content="index, follow"]
block title
title Default title
//- ----- CSS Files ----- //
link[rel='stylesheet', href='/bootstrap/dist/css/bootstrap.min.css']
link[rel='stylesheet', href='/bootstrap-material-design/dist/css/material.min.css']
body
block content
//- ----- JS Files ----- //
script[type='text/javascript', src='/jquery/dist/jquery.min.js']
script[type='text/javascript', src='/socket.io-client/socket.io.js']
script[type='text/javascript', src='/bootstrap/dist/js/bootstrap.min.js']
script[type='text/javascript', src='/bootstrap-material-design/dist/js/material.min.js']
script[type='text/javascript', src='/scripts/BelajarWebSocket.js']
1 ini salah satu fungsi template engine, jadinya kita tidak perlu banyak - banyak mendeklarasikan file js, css dan img :] . jangan lupa dari masing - masing komponent seperti doctype html
html[lang='en']
head
meta[charset='utf-8']
meta[name='viewport', content='width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no']
meta[name='description', content='Belajar WebSocket']
meta[name='keywords', content='keywords']
meta[name='author', content='Rizki Mufrizal']
meta[name="robots", content="index, follow"]
block title
title Default title
//- ----- CSS Files ----- //
link[rel='stylesheet', href='/bootstrap/dist/css/bootstrap.min.css']
link[rel='stylesheet', href='/bootstrap-material-design/dist/css/material.min.css']
body
block content
//- ----- JS Files ----- //
script[type='text/javascript', src='/jquery/dist/jquery.min.js']
script[type='text/javascript', src='/socket.io-client/socket.io.js']
script[type='text/javascript', src='/bootstrap/dist/js/bootstrap.min.js']
script[type='text/javascript', src='/bootstrap-material-design/dist/js/material.min.js']
script[type='text/javascript', src='/scripts/BelajarWebSocket.js']
6, doctype html
html[lang='en']
head
meta[charset='utf-8']
meta[name='viewport', content='width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no']
meta[name='description', content='Belajar WebSocket']
meta[name='keywords', content='keywords']
meta[name='author', content='Rizki Mufrizal']
meta[name="robots", content="index, follow"]
block title
title Default title
//- ----- CSS Files ----- //
link[rel='stylesheet', href='/bootstrap/dist/css/bootstrap.min.css']
link[rel='stylesheet', href='/bootstrap-material-design/dist/css/material.min.css']
body
block content
//- ----- JS Files ----- //
script[type='text/javascript', src='/jquery/dist/jquery.min.js']
script[type='text/javascript', src='/socket.io-client/socket.io.js']
script[type='text/javascript', src='/bootstrap/dist/js/bootstrap.min.js']
script[type='text/javascript', src='/bootstrap-material-design/dist/js/material.min.js']
script[type='text/javascript', src='/scripts/BelajarWebSocket.js']
7 dan doctype html
html[lang='en']
head
meta[charset='utf-8']
meta[name='viewport', content='width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no']
meta[name='description', content='Belajar WebSocket']
meta[name='keywords', content='keywords']
meta[name='author', content='Rizki Mufrizal']
meta[name="robots", content="index, follow"]
block title
title Default title
//- ----- CSS Files ----- //
link[rel='stylesheet', href='/bootstrap/dist/css/bootstrap.min.css']
link[rel='stylesheet', href='/bootstrap-material-design/dist/css/material.min.css']
body
block content
//- ----- JS Files ----- //
script[type='text/javascript', src='/jquery/dist/jquery.min.js']
script[type='text/javascript', src='/socket.io-client/socket.io.js']
script[type='text/javascript', src='/bootstrap/dist/js/bootstrap.min.js']
script[type='text/javascript', src='/bootstrap-material-design/dist/js/material.min.js']
script[type='text/javascript', src='/scripts/BelajarWebSocket.js']
8 dikasih doctype html
html[lang='en']
head
meta[charset='utf-8']
meta[name='viewport', content='width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no']
meta[name='description', content='Belajar WebSocket']
meta[name='keywords', content='keywords']
meta[name='author', content='Rizki Mufrizal']
meta[name="robots", content="index, follow"]
block title
title Default title
//- ----- CSS Files ----- //
link[rel='stylesheet', href='/bootstrap/dist/css/bootstrap.min.css']
link[rel='stylesheet', href='/bootstrap-material-design/dist/css/material.min.css']
body
block content
//- ----- JS Files ----- //
script[type='text/javascript', src='/jquery/dist/jquery.min.js']
script[type='text/javascript', src='/socket.io-client/socket.io.js']
script[type='text/javascript', src='/bootstrap/dist/js/bootstrap.min.js']
script[type='text/javascript', src='/bootstrap-material-design/dist/js/material.min.js']
script[type='text/javascript', src='/scripts/BelajarWebSocket.js']
9 fungsinya nanti kita akan mengambil value dari masing - masing komponent tersebut dengan bantuan JQuery.Selesai untuk layoutnya, selanjutnya buat folder
extends ./layout.jade
block title
title Belajar WebSocket
block content
div.container
div.row
div.col-xs-5.col-md-3
div.col-xs-5.col-md-6
div.panel.panel-primary
div.panel-heading
h3.panel-title Aplikasi Chat
div.panel-body
ul[id="listPesan"]
div.panel-footer
div.form-group
input[id="nama", type="text", placeholder="Masukkan Nama Anda"].form-control.floating-label
div.form-group
textarea[id="pesan", placeholder="Masukkan Pesan Anda"].form-control.floating-label
button[id="kirim", type="button"].btn.btn-primary.btn-fab.btn-raised.mdi-content-send
0 di dalam folder root folder project, buat juga folder extends ./layout.jade
block title
title Belajar WebSocket
block content
div.container
div.row
div.col-xs-5.col-md-3
div.col-xs-5.col-md-6
div.panel.panel-primary
div.panel-heading
h3.panel-title Aplikasi Chat
div.panel-body
ul[id="listPesan"]
div.panel-footer
div.form-group
input[id="nama", type="text", placeholder="Masukkan Nama Anda"].form-control.floating-label
div.form-group
textarea[id="pesan", placeholder="Masukkan Pesan Anda"].form-control.floating-label
button[id="kirim", type="button"].btn.btn-primary.btn-fab.btn-raised.mdi-content-send
1 di dalam folder extends ./layout.jade
block title
title Belajar WebSocket
block content
div.container
div.row
div.col-xs-5.col-md-3
div.col-xs-5.col-md-6
div.panel.panel-primary
div.panel-heading
h3.panel-title Aplikasi Chat
div.panel-body
ul[id="listPesan"]
div.panel-footer
div.form-group
input[id="nama", type="text", placeholder="Masukkan Nama Anda"].form-control.floating-label
div.form-group
textarea[id="pesan", placeholder="Masukkan Pesan Anda"].form-control.floating-label
button[id="kirim", type="button"].btn.btn-primary.btn-fab.btn-raised.mdi-content-send
0. Buat sebuah file extends ./layout.jade
block title
title Belajar WebSocket
block content
div.container
div.row
div.col-xs-5.col-md-3
div.col-xs-5.col-md-6
div.panel.panel-primary
div.panel-heading
h3.panel-title Aplikasi Chat
div.panel-body
ul[id="listPesan"]
div.panel-footer
div.form-group
input[id="nama", type="text", placeholder="Masukkan Nama Anda"].form-control.floating-label
div.form-group
textarea[id="pesan", placeholder="Masukkan Pesan Anda"].form-control.floating-label
button[id="kirim", type="button"].btn.btn-primary.btn-fab.btn-raised.mdi-content-send
3 di dalam folder extends ./layout.jade
block title
title Belajar WebSocket
block content
div.container
div.row
div.col-xs-5.col-md-3
div.col-xs-5.col-md-6
div.panel.panel-primary
div.panel-heading
h3.panel-title Aplikasi Chat
div.panel-body
ul[id="listPesan"]
div.panel-footer
div.form-group
input[id="nama", type="text", placeholder="Masukkan Nama Anda"].form-control.floating-label
div.form-group
textarea[id="pesan", placeholder="Masukkan Pesan Anda"].form-control.floating-label
button[id="kirim", type="button"].btn.btn-primary.btn-fab.btn-raised.mdi-content-send
1. Nah file extends ./layout.jade
block title
title Belajar WebSocket
block content
div.container
div.row
div.col-xs-5.col-md-3
div.col-xs-5.col-md-6
div.panel.panel-primary
div.panel-heading
h3.panel-title Aplikasi Chat
div.panel-body
ul[id="listPesan"]
div.panel-footer
div.form-group
input[id="nama", type="text", placeholder="Masukkan Nama Anda"].form-control.floating-label
div.form-group
textarea[id="pesan", placeholder="Masukkan Pesan Anda"].form-control.floating-label
button[id="kirim", type="button"].btn.btn-primary.btn-fab.btn-raised.mdi-content-send
3 kita akan isi dengan konfigurasi JQuery dan Socket.IO. Berikut codingan nya.'use strict';
var socket = io[];
var DataChatKirim = {};
$[document].ready[function[] {
$['#kirim'].on['click', function[] {
DataChatKirim.nama = $['#nama'].val[];
DataChatKirim.pesan = $['#pesan'].val[];
socket.emit['chat:pesan', DataChatKirim];
$['#nama'].val[''];
$['#pesan'].val[''];
}];
}];
socket.on['chat:pesan', function[DataChat] {
if [DataChatKirim.nama === DataChat.nama] {
$['#listPesan'].prepend[$[''].text[DataChat.nama + ' : ' + DataChat.pesan]];
} else {
$['#listPesan'].prepend[$[''].text[DataChat.nama + ' : ' + DataChat.pesan]];
}
}];
Berikut penjelasan singkat dari codingan diatas.
6 berfungsi untuk mendeklarasikan koneksi websocketextends ./layout.jade block title title Belajar WebSocket block content div.container div.row div.col-xs-5.col-md-3 div.col-xs-5.col-md-6 div.panel.panel-primary div.panel-heading h3.panel-title Aplikasi Chat div.panel-body ul[id="listPesan"] div.panel-footer div.form-group input[id="nama", type="text", placeholder="Masukkan Nama Anda"].form-control.floating-label div.form-group textarea[id="pesan", placeholder="Masukkan Pesan Anda"].form-control.floating-label button[id="kirim", type="button"].btn.btn-primary.btn-fab.btn-raised.mdi-content-send
7 deklarasi untuk data chat yang dikirimextends ./layout.jade block title title Belajar WebSocket block content div.container div.row div.col-xs-5.col-md-3 div.col-xs-5.col-md-6 div.panel.panel-primary div.panel-heading h3.panel-title Aplikasi Chat div.panel-body ul[id="listPesan"] div.panel-footer div.form-group input[id="nama", type="text", placeholder="Masukkan Nama Anda"].form-control.floating-label div.form-group textarea[id="pesan", placeholder="Masukkan Pesan Anda"].form-control.floating-label button[id="kirim", type="button"].btn.btn-primary.btn-fab.btn-raised.mdi-content-send
8 merupakan deklarasi jquery untuk awal sebuah dokumentextends ./layout.jade block title title Belajar WebSocket block content div.container div.row div.col-xs-5.col-md-3 div.col-xs-5.col-md-6 div.panel.panel-primary div.panel-heading h3.panel-title Aplikasi Chat div.panel-body ul[id="listPesan"] div.panel-footer div.form-group input[id="nama", type="text", placeholder="Masukkan Nama Anda"].form-control.floating-label div.form-group textarea[id="pesan", placeholder="Masukkan Pesan Anda"].form-control.floating-label button[id="kirim", type="button"].btn.btn-primary.btn-fab.btn-raised.mdi-content-send
9 merupakan deklarasik jquery dengan mengambil sebuah id dengan namaextends ./layout.jade block title title Belajar WebSocket block content div.container div.row div.col-xs-5.col-md-3 div.col-xs-5.col-md-6 div.panel.panel-primary div.panel-heading h3.panel-title Aplikasi Chat div.panel-body ul[id="listPesan"] div.panel-footer div.form-group input[id="nama", type="text", placeholder="Masukkan Nama Anda"].form-control.floating-label div.form-group textarea[id="pesan", placeholder="Masukkan Pesan Anda"].form-control.floating-label button[id="kirim", type="button"].btn.btn-primary.btn-fab.btn-raised.mdi-content-send
0, id ini berasal dari sebuah button, kemudian jika ada yang mengirim pesan maka function dibawahnya akan dijalankan.'use strict'; var socket = io[]; var DataChatKirim = {}; $[document].ready[function[] { $['#kirim'].on['click', function[] { DataChatKirim.nama = $['#nama'].val[]; DataChatKirim.pesan = $['#pesan'].val[]; socket.emit['chat:pesan', DataChatKirim]; $['#nama'].val['']; $['#pesan'].val['']; }]; }]; socket.on['chat:pesan', function[DataChat] { if [DataChatKirim.nama === DataChat.nama] { $['#listPesan'].prepend[$[''].text[DataChat.nama + ' : ' + DataChat.pesan]]; } else { $['#listPesan'].prepend[$[''].text[DataChat.nama + ' : ' + DataChat.pesan]]; } }];
1 berfungsi untuk mengambil data nama, dapat dilihat bahwa'use strict'; var socket = io[]; var DataChatKirim = {}; $[document].ready[function[] { $['#kirim'].on['click', function[] { DataChatKirim.nama = $['#nama'].val[]; DataChatKirim.pesan = $['#pesan'].val[]; socket.emit['chat:pesan', DataChatKirim]; $['#nama'].val['']; $['#pesan'].val['']; }]; }]; socket.on['chat:pesan', function[DataChat] { if [DataChatKirim.nama === DataChat.nama] { $['#listPesan'].prepend[$[''].text[DataChat.nama + ' : ' + DataChat.pesan]]; } else { $['#listPesan'].prepend[$[''].text[DataChat.nama + ' : ' + DataChat.pesan]]; } }];
2 berfungsi untuk mengambil data yang berasal dari id'use strict'; var socket = io[]; var DataChatKirim = {}; $[document].ready[function[] { $['#kirim'].on['click', function[] { DataChatKirim.nama = $['#nama'].val[]; DataChatKirim.pesan = $['#pesan'].val[]; socket.emit['chat:pesan', DataChatKirim]; $['#nama'].val['']; $['#pesan'].val['']; }]; }]; socket.on['chat:pesan', function[DataChat] { if [DataChatKirim.nama === DataChat.nama] { $['#listPesan'].prepend[$[''].text[DataChat.nama + ' : ' + DataChat.pesan]]; } else { $['#listPesan'].prepend[$[''].text[DataChat.nama + ' : ' + DataChat.pesan]]; } }];
3.'use strict'; var socket = io[]; var DataChatKirim = {}; $[document].ready[function[] { $['#kirim'].on['click', function[] { DataChatKirim.nama = $['#nama'].val[]; DataChatKirim.pesan = $['#pesan'].val[]; socket.emit['chat:pesan', DataChatKirim]; $['#nama'].val['']; $['#pesan'].val['']; }]; }]; socket.on['chat:pesan', function[DataChat] { if [DataChatKirim.nama === DataChat.nama] { $['#listPesan'].prepend[$[''].text[DataChat.nama + ' : ' + DataChat.pesan]]; } else { $['#listPesan'].prepend[$[''].text[DataChat.nama + ' : ' + DataChat.pesan]]; } }];
4 berfungsi untuk mengirim data chat ke server melalui websocket'use strict'; var socket = io[]; var DataChatKirim = {}; $[document].ready[function[] { $['#kirim'].on['click', function[] { DataChatKirim.nama = $['#nama'].val[]; DataChatKirim.pesan = $['#pesan'].val[]; socket.emit['chat:pesan', DataChatKirim]; $['#nama'].val['']; $['#pesan'].val['']; }]; }]; socket.on['chat:pesan', function[DataChat] { if [DataChatKirim.nama === DataChat.nama] { $['#listPesan'].prepend[$[''].text[DataChat.nama + ' : ' + DataChat.pesan]]; } else { $['#listPesan'].prepend[$[''].text[DataChat.nama + ' : ' + DataChat.pesan]]; } }];
5 merupakan perintah jquery untuk menghapus data yang terdapat di dalam form inputan'use strict'; var socket = io[]; var DataChatKirim = {}; $[document].ready[function[] { $['#kirim'].on['click', function[] { DataChatKirim.nama = $['#nama'].val[]; DataChatKirim.pesan = $['#pesan'].val[]; socket.emit['chat:pesan', DataChatKirim]; $['#nama'].val['']; $['#pesan'].val['']; }]; }]; socket.on['chat:pesan', function[DataChat] { if [DataChatKirim.nama === DataChat.nama] { $['#listPesan'].prepend[$[''].text[DataChat.nama + ' : ' + DataChat.pesan]]; } else { $['#listPesan'].prepend[$[''].text[DataChat.nama + ' : ' + DataChat.pesan]]; } }];
6 sama seperti pada server, function ini berfungsi untuk menunggu response dari server, jika ada response maka perintah dibawah function ini akan dijalankan.'use strict'; var socket = io[]; var DataChatKirim = {}; $[document].ready[function[] { $['#kirim'].on['click', function[] { DataChatKirim.nama = $['#nama'].val[]; DataChatKirim.pesan = $['#pesan'].val[]; socket.emit['chat:pesan', DataChatKirim]; $['#nama'].val['']; $['#pesan'].val['']; }]; }]; socket.on['chat:pesan', function[DataChat] { if [DataChatKirim.nama === DataChat.nama] { $['#listPesan'].prepend[$[''].text[DataChat.nama + ' : ' + DataChat.pesan]]; } else { $['#listPesan'].prepend[$[''].text[DataChat.nama + ' : ' + DataChat.pesan]]; } }];
7 berfungsi untuk menambah tag'use strict'; var socket = io[]; var DataChatKirim = {}; $[document].ready[function[] { $['#kirim'].on['click', function[] { DataChatKirim.nama = $['#nama'].val[]; DataChatKirim.pesan = $['#pesan'].val[]; socket.emit['chat:pesan', DataChatKirim]; $['#nama'].val['']; $['#pesan'].val['']; }]; }]; socket.on['chat:pesan', function[DataChat] { if [DataChatKirim.nama === DataChat.nama] { $['#listPesan'].prepend[$[''].text[DataChat.nama + ' : ' + DataChat.pesan]]; } else { $['#listPesan'].prepend[$[''].text[DataChat.nama + ' : ' + DataChat.pesan]]; } }];
8 pada tag'use strict'; var socket = io[]; var DataChatKirim = {}; $[document].ready[function[] { $['#kirim'].on['click', function[] { DataChatKirim.nama = $['#nama'].val[]; DataChatKirim.pesan = $['#pesan'].val[]; socket.emit['chat:pesan', DataChatKirim]; $['#nama'].val['']; $['#pesan'].val['']; }]; }]; socket.on['chat:pesan', function[DataChat] { if [DataChatKirim.nama === DataChat.nama] { $['#listPesan'].prepend[$[''].text[DataChat.nama + ' : ' + DataChat.pesan]]; } else { $['#listPesan'].prepend[$[''].text[DataChat.nama + ' : ' + DataChat.pesan]]; } }];
9, id'use strict'; var socket = io[]; var DataChatKirim = {}; $[document].ready[function[] { $['#kirim'].on['click', function[] { DataChatKirim.nama = $['#nama'].val[]; DataChatKirim.pesan = $['#pesan'].val[]; socket.emit['chat:pesan', DataChatKirim]; $['#nama'].val['']; $['#pesan'].val['']; }]; }]; socket.on['chat:pesan', function[DataChat] { if [DataChatKirim.nama === DataChat.nama] { $['#listPesan'].prepend[$[''].text[DataChat.nama + ' : ' + DataChat.pesan]]; } else { $['#listPesan'].prepend[$[''].text[DataChat.nama + ' : ' + DataChat.pesan]]; } }];
0 berasal dari tagweb: node app.js
9 sehingga apabila ada chat yang masuk, maka tag'use strict'; var socket = io[]; var DataChatKirim = {}; $[document].ready[function[] { $['#kirim'].on['click', function[] { DataChatKirim.nama = $['#nama'].val[]; DataChatKirim.pesan = $['#pesan'].val[]; socket.emit['chat:pesan', DataChatKirim]; $['#nama'].val['']; $['#pesan'].val['']; }]; }]; socket.on['chat:pesan', function[DataChat] { if [DataChatKirim.nama === DataChat.nama] { $['#listPesan'].prepend[$[''].text[DataChat.nama + ' : ' + DataChat.pesan]]; } else { $['#listPesan'].prepend[$[''].text[DataChat.nama + ' : ' + DataChat.pesan]]; } }];
8 akan ditambah secara otomatis, ini merupakan salah satu konsep dari JQuery yaitu DOM [data object ].'use strict'; var socket = io[]; var DataChatKirim = {}; $[document].ready[function[] { $['#kirim'].on['click', function[] { DataChatKirim.nama = $['#nama'].val[]; DataChatKirim.pesan = $['#pesan'].val[]; socket.emit['chat:pesan', DataChatKirim]; $['#nama'].val['']; $['#pesan'].val['']; }]; }]; socket.on['chat:pesan', function[DataChat] { if [DataChatKirim.nama === DataChat.nama] { $['#listPesan'].prepend[$[''].text[DataChat.nama + ' : ' + DataChat.pesan]]; } else { $['#listPesan'].prepend[$[''].text[DataChat.nama + ' : ' + DataChat.pesan]]; } }];
Uji Coba Aplikasi Chat
Silahkan jalankan aplikasi dengan perintah
web: node app.js
3 atau web: node app.js
4 kemudian hit pada browser dengan url web: node app.js
5 kemudian buka 2 browser lakukan chat. Berikut adalah hasilnya pada saat anda chat.Berikut tampilan list chat
Deploy Aplikasi ke Heroku
Heroku merupakan hosting gratis untuk percobaan aplikasi, heroku mendukung beberapa bahasa pemrograman diantaranya adalah javascript, disini node js sebagai javascript yang jalan pada bagian server. Silahkan daftar di Heroku kemudian jangan lupa setting key ssh anda.
Buatlah sebuah file
web: node app.js
6 di dalam root folder, kemudian isikan kodingan berikut.web: node app.js
buat sebuah file
web: node app.js
7 agar folder web: node app.js
8 dan web: node app.js
9 tidak ikut dicommit, masukkan codingan berikut pada file web: node app.js
7.bower_components/
node_modules/
Inisialisasi dengan menggunakan perintah
bower_components/
node_modules/
1, buatlah sebuat project pada dashboard heroku. Kemudian buka file bower_components/
node_modules/
2 pada bagian extends ./layout.jade
block title
title Belajar WebSocket
block content
div.container
div.row
div.col-xs-5.col-md-3
div.col-xs-5.col-md-6
div.panel.panel-primary
div.panel-heading
h3.panel-title Aplikasi Chat
div.panel-body
ul[id="listPesan"]
div.panel-footer
div.form-group
input[id="nama", type="text", placeholder="Masukkan Nama Anda"].form-control.floating-label
div.form-group
textarea[id="pesan", placeholder="Masukkan Pesan Anda"].form-control.floating-label
button[id="kirim", type="button"].btn.btn-primary.btn-fab.btn-raised.mdi-content-send
1 ganti bower_components/
node_modules/
4 menjadi"postinstall": "./node_modules/bower/bin/bower install"
hasilnya seperti ini
"scripts": {
"postinstall": "./node_modules/bower/bin/bower install"
}
Install bower pada aplikasi dengan perintah
bower_components/
node_modules/
5. Disini penulis membuat aplikasi pada heroku dengan nama bower_components/
node_modules/
6 kemudian jalankan perintah bower_components/
node_modules/
7 pada root folder project. Tambah semua file agar dapat dicommit dengan perintah bower_components/
node_modules/
8 Kemudian commit dengan perintah bower_components/
node_modules/
9 kemudian push semua source code ke heroku dengan perintah "postinstall": "./node_modules/bower/bin/bower install"
0. Tunggu hingga selesai, jika berhasil maka akan muncul seperti ini.Oke aplikasi chat akhirnya berhasil online :D silahkan akses di Aplikasi Chat :] . Sekian tutorial membuat aplikasi chat dengan teknologi node js dan socket.io dan Terima kasih :]. Untuk source code lengkap, penulis publish di Belajar WebSocket.