Sunday, June 22, 2014

Aplikasi chat berbasis web menggunakan Socket.io dan NodeJS - Part 1

Sebagai konsultan, kami di Nostra seringkali mendapat kesempatan dan di-haruskan bekerja langsung on-site di kantor client dengan memakai PC yang telah di-sediakan dan biasanya akses administratif serta jaringannya di lock-down sesuai dengan policy perusahaan tersebut.

Sering kali komunikasi antar team member menjadi terhambat apalagi kalau meja-nya saling berjauhan, karena tidak mungkin saling bersautan dengan nada suara tinggi atau menghampiri kesana kemari hanya untuk hal kecil yang tidak membutuhkan lisan (misal: Technical Leader menginformasikan kesalahan kecil yg terdapat dalam aplikasi yang sedang dikerjakan, sehingga programmer dapat langsung dapat memperbaikinya). Masalah ini dapat di tanggulangi dengan memakai IM seperti Skype, tetapi biasanya tidak memungkinkan karena policy dari perusahan client.

Hal inilah yang menginspirasi saya untuk membuat aplikasi chat sederhana berbasis web (Ya..., akses ke internet melalui web browser pada umumnya tidak di anggap "membahayakan" secara internal sehingga di perbolehkan) yang nantinya dapat berguna bagi kami yang sedang bekerja di kantor client dan mengalami masalah serupa.

Technical Feasibility


Untuk membuat aplikasi ini kita membutuhkan suatu teknologi yang memungkinkan komunikasi dua arah (full-duplex) antara web browser dan server sehingga data di web browser akan terupdate secara real-time apabila data yang di server mengalami perubahan. Seperti yang sudah kita ketahui aplikasi web dibangun di atas protokol HTTP di mana protokol ini tidak men-support komunikasi dua arah (biderectional communication) antara client (web browser) dan server. Untuk mengakali keterbatasan protokol HTTP ini, ada dua teknik yang pada saat ini di pakai, yaitu:

  1. Periodic Polling, yaitu teknik di mana si Client melakukan request secara berkala ke Server untuk menge-cek apakah ada data yang baru dan kemudian melakukan update pada data yang sedang display. 
  2. Long-polling, yaitu teknik dimana si Client melakukan request untuk menge-cek apakah ada data yang baru namun si Server tidak langsung me-respon tetapi akan menjaga (hold) koneksi tetap terbuka selama tidak terdapat data yang baru. Teknik long-polling inilah yang saat di pakai untuk membuat aplikasi chat berbasis web seperti Gmail chat, Facebook chat, dll.

Sebagai alternatif dari dua teknik tradisional di atas, kita dapat menggunakan fitur HTML5 terbaru yaitu WebSocket, tetapi karena standar HTML5 relatif masih baru, hanya beberapa browser versi terbaru yang men-support WebSocket sehingga kurang fleksibel.

Socket.io


Socket.io adalah library JavaScript yang memungkinkan komunikasi real-time antara web browser dan server. Library ini terdiri dari dua bagian, yang berjalan pada web browser dan yang berjalan pada server sebagai NodeJS module. Socket.io akan menggunakan WebSocket sebagai sarana tansport utama dan akan meng-fallback ke beberapa teknik transport lainnya apabila WebSocket tidak tersedia, seperti Flash (menggunakan socket), Ajax long-pooling, atau iframe, sehingga tetap dapat berjalan walaupun browser tidak meng-support WebSocket. Socket.io juga memiliki fitur yang sangat berguna yaitu dengan sendirinya akan mencoba membuat ulang koneksi (reconnect) apabila koneksi terputus.

Environment Setup


Karena Socket.io berjalan di atas NodeJS sebagai module, kita harus terlebih dahulu meng-install NodeJS. Jika anda memakai Windows atau Mac bisa langsung ke http://nodejs.org/download untuk men-download installer nya. Karena saya memakai ArchLinux jadi saya akan menginstall lewat pacman:

$ pacman -S nodejs

(untuk distro linux lainnya bisa mengikuti langkah-langkah yang di berikan disini)

Setelah NodeJS terinstall, lanjutkan dengan meng-install module-module yang di perlukan yaitu:
- Socket.io : library utama yg akan di gunakan
- ExpressJS : http server framework untuk NodeJS (ini akan digunakan untuk melayani file html ke browser)

Untuk meng-install nya kita akan menggunakan Node Package Manager (npm) yang sudah tersedia pada saat kita menginstall NodeJS.

Agar aplikasi yang akan di buat lebih terstruktur, semua file-file yang bersangkutan akan di letakkan pada satu tempat.
Buat folder NostraChat. Folder ini akan digunakan sebagai project root.

$ mkdir NostraChat
$ cd NostraChat

Buat file package.json pada folder tersebut dengan isi sebagai berikut:

{
    "name": "NostraChat",
    "version": "1.0.0",
    "description": "Simple Chat Web App",
    "dependencies": {
        "socket.io": "latest",
        "express": "latest"
    },
    "author": "nostra-dev"
}

Lalu di console jalankan perintah:

$ npm install

Ini akan membutuhkan beberapa waktu karena npm harus men-download module-module tersebut dari internet. Saat npm selesai, module-module tersebut akan ter-install di ./node_modules

Struktur Aplikasi


Aplikasi chat yang akan kita kembangkan ini terdiri dari server (backend) dan sebuah file html sebagai halaman utama (front-end).

Langkah pertama adalah menyiapkan server untuk me-respon dengan halaman utama yang berupa
file html saat mendapatkan request dari web browser. Buat sub-folder "public", dan di dalam folder ini buat file bernama "index.html" dengan isi sebagai berikut:

<!DOCTYPE html> 
<html> 
<head> 
    <title>Nostra Chat</title> 
    <style type="text/css"> 
        body, div, p { margin: 0; padding: 0; } 
        body { font-family: "Arial"; } 
        form { position: fixed; bottom: 0; width: 100%; margin: 0; padding: 0; } 
        form textarea { width: 100%; height: 50px; padding: 10px; margin: 0; border: 1px solid #bbb; }
        #messages { list-style-type: none; margin: 0; padding: 0; background: #fff; } 
        #messages li { padding: 5px 10px; }         
        #main { 
            width: 85%; 
            margin: 10px; 
        } 
        #side { 
            width: 15%; 
            background: #fff; 
            position: absolute; 
            top: 0; bottom: 75px; right: 0; 
            border: 1px solid #bbb; 
        } 
        #side .header { 
            background: #eee; 
            color: #333; 
            margin: 0; 
            padding: 5px 10px; 
            font-weight: bold; 
            position: relative; 
            border-bottom: 1px solid #bbb; 
        } 
        #side .header p { 
            width: 100%; 
        } 
        #side .header #logout { 
            text-align: right; 
            position: absolute; 
            right: 10px; 
            text-decoration: none; 
            color: #888; 
        } 
        #side .header #logout:hover { 
            color: #333; 
        } 
        #user-list { 
            list-style-type: none; margin: 0; padding: 0; 
            padding: 5px 10px; 
        } 
        #user-list .current-user { font-weight: bold; } 
    </style> 
</head> 

<body> 
    <div id="main"> 
        <ul id="messages"> 
            <!--<li class="my-message">Hi server</li>--> 
            <!--<li>Hello client</li>--> 
        </ul> 
    </div> 
     
    <div id="side"> 
        <p class="header">Online</p> 
        <ul id="user-list"> 
            <!--<li class="current-user">Fani</li>--> 
        </ul> 
    </div> 
     
    <form action=""> 
      <textarea name="messageText" autocomplete="off"></textarea> 
    </form>       
</body> 
</html>

Kode untuk men-setup server di letakkan pada file bernama "server.js" di project root (NostraChat).
File ini akan di jalankan (execute) oleh NodeJS.

Adapun isi dari file server.js tersebut adalah sebagai berikut, kodenya sudah saya berikan comment, jadi saya rasa sudah menjelaskan dengan sendiri-nya :)

var express = require('express'), 
    app = express(), 
    port = 3000 
    ; 

/** 
 * Meng-konfigurasi express untuk meng-look-up file html 
 * dari directory bernama "public" 
 */ 
app.use(express.static(__dirname + '/public')); 

/** 
 * Pada saat browser me-request path "/" 
 * response dengan file bernama "index.html" 
 */ 
app.get('/', function(req, res){
    res.sendfile('index.html'); 
}); 

/* 
 * Meng-konfigurasi express untuk listen pada 
 * port yang telah di tentukan 
 */ 
app.listen(port, function(){ 
    console.log('listening on *:' + port); 
});

Jalankan server dengan:

$ node server.js

Lalu buka di browser: http://localhost:3000

So far so good, halaman utama aplikasi sudah berjalan tetapi belum fungsional, di sinilah saatnya kita meng-integrasikan Socket.io pada aplikasi agar menjadi fungsional.

Stay tuned for Part 2...

1 comment: