WebSocket

WebSocket merupakan sebuah protokol komunikasi dua arah yang dapat digunakan oleh browser. Jika pada AJAX kita hanya dapat melakukan komunikasi satu arah dengan mengirimkan request kepada server dan menunggu balasannya, maka menggunakan WebSocket kita tidak hanya dapat mengirimkan request kepada server, tetapi juga menerima data dari server tanpa harus mengirimkan request terlebih dahulu. Hal ini berarti ketika menggunakan WebSocket pengguna harus terus menerus terkoneksi dengan server, dan kita memerlukan sebuah server khusus untuk dapat menjalankan aplikasi WebSocket dengan benar. Sederhananya, perhatikan gambar berikut:

_images/AJAXvsWebSocket.png

Dari gambar di atas, kita dapat melihat bagaimana dalam kasus AJAX, setiap request dari pengguna maupun respon dari server dilakukan secara terpisah. Jika ingin mengirimkan request ke server, kita perlu membuka koneksi baru yang kemudian akan dibalas oleh server seperti ia membalas permintaan halaman HTML biasa. Server juga tidak dapat langsung melakukan pengiriman data ke klien tanpa ada permintaan terlebih dahulu. Hal ini berbeda dengan pola komunikasi WebSocket, di mana koneksi berjalan tanpa terputus dan server dapat mengirimkan data atau perintah tanpa harus ada permintaan dari pengguna terlebih dahulu. Dengan begitu, WebSocket bahkan juga memungkinkan server mengirimkan data atau perintah ke semua klien yang terkoneksi, misalkan untuk memberikan notifikasi global.

Untuk dapat melihat langsung bagaimana cara kerja WebSocket, kita akan langsung melakukan eksperimen. Objek yang diperlukan untuk menggunakan WebSocket dari browser adalah WebSocket. Tetapi sebelumnya, kita memerlukan sedikit persiapan terlebih dahulu, yaitu komponen server dari WebSocket.

Komponen Server WebSocket

Teknologi WebSocket membutuhkan cara penggunaan yang sama sekali berbeda dibandingkan dengan AJAX. Jika pada AJAX kita dapat mengguankan komponen server yang sama dengan server HTTP pada umumnya, untuk WebSocket kita memerlukan komponen server khusus. Hal ini disebabkan oleh model komunikasi WebSocket yang mengharuskan pengguna terkoneksi dengan server sepanjang aplikasi masih digunakan. Arsitektur server yang diperlukan untuk melayani banyak koneksi terbuka seperti ini tentu berbeda dengan arsitektur yang dibutuhkan untuk koneksi satu arah seperti pada HTTP. Ketika menggunakan WebSocket, biasanya kita akan memerlukan komponen server (beserta kode sisi server) khusus.

Adapun beberapa contoh komponen server untuk WebSocket yaitu:

  1. Socket.IO (Javascript)
  2. SignalR (.Net)
  3. Jetty (JVM)
  4. Event Machine (Ruby)
  5. Tornado (Python)

Bahasa yang disebutkan pada daftar di atas adalah bahasa yang digunakan pada sisi server.

Persiapan Eksperimen WebSocket

Sebelum kita dapat mencoba menggunakan WebSocket, terlebih dahulu kita akan perlu membangun komponen server yang dapat mengerti protokol WebSocket, dan dapat mengerti pesan yang akan kita kirimkan kepada mereka. Untuk memudahkan pembaca, sebuah komponen server khusus telah disiapkan. Silahkan download sampel komponen server (websocket-sample) ini terlebih dahulu.

Terdapat dua buah server yang diberikan, yaitu:

  1. index.js merupakan komponen yang dirancang sebagai server dari sistem chatting sederhana.
  2. zero.js merupakan komponen yang dirancang sebagai server sistem menonton game (seperti twitch.tv) sederhana.

Kita akan membangun klien dari index.js dari awal, sementara klien untuk zero.js akan dimodifikasi dari contoh permainan sederhana yang sudah dipersiapkan sebelumnya. Silahkan download juga kode untuk permainan serderhana tersebut, dan coba pelajari cara kerjanya.

Menjalankan server WebSocket dari kedua kode tersebut juga sangat mudah, cukup eksekusi kode dengan NodeJS:

1
2
$ node index.js
$ node zero.js

Setelah memilki semua komponen dasar yang diperlukan, kita akan mulai mempelajari WebSocket dengan menelaah objek WebSocket terlebih dahulu.

Membuat Objek WebSocket

Pembuatan objek WebSocket (selanjutnya dirujuk sebagai ws saja) sangat mudah. Kita dapat langsung memanggil constructor dari objek tanpa perlu melakukan pengecekan tambahan. Berikut adalah contoh pembuatan objek WebSocket baru:

1
var ws = new WebSocket("ws://www.example.com/socketserver");

Dan kita telah membuat sebuah objek WebSocket, sekaligus mencoba melakukan koneksi ke alamat yang diberikan pada constructor. Constructor dari ws juga memiliki parameter kedua yang bersifat opsional. Parameter kedua ini dapat berupa sebuah string ataupun array dari string, yang berisi nama dari subprotokol WebSocket yang akan kita gunakan. Subprotokol merupakan “pesan” tambahan yang dapat kita kirimkan ke server agar server mendapatkan informasi tambahan yang dibutuhkan untuk memberikan respon. Subprotokol ini dibuat oleh pengembang sendiri, dan baik klien maupun server harus dapat mengerti subprotokol yang dikirimkan. Kegunaan utama dari subprotokol adalah agar baik klien maupun server dapat yakin bahwa lawan bicaranya benar-benar mengerti pesan yang dikirimkan maupun diterima. Kita tidak ingin server Dota2 versi 1 berkomunikasi dengan klien Dota2 versi 2 misalnya.

Penambahan subprotokol pada constructor WebSocket tidak rumit sama sekali:

1
2
var ws1 = new WebSocket("ws://www.example.com/socketserver", "dota2v1");
var ws2 = new WebSocket("ws://www.example.com/socketserver", ["dota2v1", "dota2v2"]);

Ketika kita mengirimkan array sebagai parameter kedua, berarti kita memberitahukan ke server bahwa klien yang dibangun dapat mengerti semua protokol yang ada di dalam array tersebut. Begitupun, pada akhirnya server lah yang menentukan protokol mana yang akan digunakan. Klien kemudian dapat mengelola data atau perintah sesuai dengan protokol yang digunakan server.

Menanggapi Server WebSocket

Setelah membuka koneksi, tentunya kita ingin berinteraksi dengan server. Pertama-tama, mari kita lihat terlebih dahulu bagaimana cara menangani perintah maupun data yang diberikan oleh server kepada kita.

Terdapat empat method utama yang dapat kita gunakan untuk menangani data dan perintah yang dikirimkan server:

  1. ws.onerror, method yang dijalankan ketika terjadi kesalahan pada koneksi dengan server. Bersifat opsional.
  2. ws.onclose, method yang dijalankan ketika koneksi dengan server telah ditutup. Bersifat opsional. Memiliki satu parameter, CloseEvent yang menyimpan detil pesan kesalahan yang terjadi.
  3. ws.onopen, method yang dijalankan pertama kali ketika telah tersambung dengan server. Bersifat opsional.
  4. ws.onmessage, method yang dijalankan ketika menerima pesan dari server. Memiliki satu parameter yang berisi MessageEvent, sebuah objek event yang juga menyimpan data berupa pesan dari server melalui properti MessageEvent.data.

Keempat method yang ada di atas dapat digunakan semuanya ataupun hanya ws.onmessage saja. Karena model pemrograman yang bersifat *event based*, kita cukup hanya menspesifikasikan fungsi yang dijalankan pada setiap event di atas saja. Browser akan secara otomatis mengeksekusi kode ketika event terjadi. Berikut adalah contoh penggunaan keempat fungsi di atas:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
var ws = new WebSocket("ws://www.example.com/socketserver");

ws.onopen = function() {
    console.log("Koneksi berhasil!");
};

ws.onerror = function () {
    console.log("Koneksi gagal.");
};

ws.onclose = function (event) {
    console.log("Koneksi telah ditutup. Pesan penutupan: " + event.code);
};

ws.onmessage = function (message) {
    var data = JSON.parse(message.data);

    // lakukan sesuatu dengan data
};

Perhatikan bagaimana kita menggunakan JSON.parse untuk melakukan pembacaan data pada ws.onmessage. Meskipun kita dapat menggunakan format lain seperti XML atau bahkan Blob untuk data yang diberikan server, JSON merupakan format yang paling umum. Intinya adalah kita dapat menggunakan format apapun untuk bertukar data, selama klien dan server mengerti format tersebut.

Berbicara dengan Server

Mengirimkan data atau perintah ke server WebSocket dapat dilakukan dengan menggunakan method ws.send. Penggunaannya sangat gamblang:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
ws.send("Data Server"); // mengirimkan string

// atau bahkan
var obj = {
    message: "Sebuah Pesan Rahasia",
    key: "F5-A1-00-32-E4",
    command: "Run"
};

ws.send(JSON.stringify(obj));

ws.send menerima hanya satu parameter, yang dapat berisi DOMString, ArrayBuffer, maupun Blob. Pada kode di atas kita hanya menggunakan string (DOMString) saja, bahkan untuk objek yang akan dikirimkan ke server.

Studi kasus

Sekilas penggunaan WebSocket terlihat cukup mudah dan sederhana. Untuk lebih mendalami pengertian akan WebSocket, kita akan langsung mencoba membangun aplikasi klien WebSocket. Ingat, terlebih dahulu kita perlu server khusus dalam ujicoba ini. Silahkan lihat bagian Persiapan Eksperimen WebSocket untuk detail aplikasi server yang dibutuhkan dalam eksperimen ini.

Kasus 1: Aplikasi Chatting

Aplikasi yang paling pertama akan kita kembangkan adalah aplikasi chatting sederhana. Agar dapat berfokus pada pengiriman dan penerimaan pesan saja, kita akan menggunakan kode HTML yang sangat sederhana, sebagai berikut:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
<!DOCTYPE html>
    <html lang="en">
    <head>
            <meta charset="UTF-8">
            <title>Websocket test</title>
    </head>
    <body>
            <ul id="chat"></ul>
            <input type="text" id="chatinput">

            <script type="text/javascript" src="chat.js"></script>
    </body>
    </html>

Selanjutnya, kita akan mengisikan chat.js dengan kode koneksi ke server WebSocket, sesuai dengan yang kita pelajari sejauh ini:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
var chat      = document.querySelector("#chat"),
        chatinput = document.querySelector("#chatinput"),
        websocket = new WebSocket("ws://127.0.0.1:8080"), // #1
        addChat   = function (data) {                     // #2
                    var newChat = document.createElement("li"),
                        newText = document.createTextNode(data);

                    newChat.appendChild(newText);
                    chat.appendChild(newChat);
        };

    // #3
    websocket.onmessage = function (event) {
            addChat(event.data);
    }

// #4
    chatinput.addEventListener("keydown", function (evt) {
            if (evt.keyCode === 13) {
                    addChat(chatinput.value);
                    websocket.send(chatinput.value); // #5
                    chatinput.value = "";

                    return false;
            }
    });

Penjelasan kode (sesuai dengan nomor yang diberikan pada komentar):

  1. Pembuatan objek WebSocket untuk membuka koneksi dengan server. Pastikan IP dan port yang digunakan benar pada bagian ini.
  2. Fungsi addChat merupakan fungsi yang akan kita gunakan untuk menambahkan chat baru ke elemen #chatinput.
  3. Setelah membuat semua variabel dan fungsi yang dibutuhkan, kita kemudian mengikatkan WebSocket.onmessage kepada satu fungsi anonim. Fungsi ini tugasnya sangat sederhana: menambahkan chat baru dengan data yang didapatkan dari server. Hal ini berarti chat baru yang ditambahkan melalui WebSocket.onmessage selalu adalah chat yang dikirimkan oleh pengguna lain.
  4. Pada langkah ini kita menambahakn pemantau event keydown pada #chat, yang akan mengirimkan data ke server ketika pengguna menekan tombol Enter (key code 13).
  5. Mengirimkan data ke server sangat sederhana, cukup dengan satu baris perintah ini saja.

Seperti yang dapat kita lihat, implementasi WebSocket, baik dari sisi pengiriman data ke server maupun pengolahan data yang diterima dari server cukup mudah. Yang menjadi tantangan dalam penggunaan WebSocket biasanya adalah kapan pengiriman data dilakukan, dan apa yang harus dilakukan terhadap data yang dikirimkan oleh server.

Berikut adalah tampilan akhir dari aplikasi yang kita kembangkan:

_images/ChatAppSample.gif
comments powered by Disqus
Kembali ke bertzzie.com