Memperkenalkan WebSockets - Membawa Socket ke Web

Masalah: Koneksi klien-server dan server-klien berlatensi rendah

Sebagian besar web dibangun berdasarkan apa yang disebut paradigma permintaan/respons dalam HTTP. Klien memuat halaman web dan tidak ada yang terjadi sampai pengguna mengklik halaman berikutnya. Sekitar tahun 2005, AJAX mulai membuat web terasa lebih dinamis. Namun, semua komunikasi HTTP dikendalikan oleh klien, yang memerlukan interaksi pengguna atau polling berkala untuk memuat data baru dari server.

Teknologi yang memungkinkan server mengirim data ke klien tepat ketika server mengetahui bahwa data baru tersedia telah dilakukan cukup lama. Tombol ini menggunakan nama seperti 'Push' atau 'Comet'. Salah satu peretasan paling umum untuk membuat ilusi koneksi yang dimulai server disebut long polling. Dengan polling yang panjang, klien membuka koneksi HTTP ke server yang membuatnya tetap terbuka hingga mengirimkan respons. Setiap kali server benar-benar memiliki data baru, server akan mengirimkan respons (teknik lain melibatkan permintaan Flash, multipart XHR, dan disebut dengan htmlfiles). Polling panjang dan teknik lainnya berfungsi cukup baik. Anda menggunakannya setiap hari dalam aplikasi seperti obrolan Gmail.

Namun, semua solusi ini memiliki satu masalah: Keduanya membawa overhead HTTP, yang tidak membuatnya cocok untuk aplikasi latensi rendah. Coba bayangkan game first person shooter multiplayer di browser atau game online lainnya dengan komponen realtime.

Memperkenalkan WebSocket: Membawa soket ke web

Spesifikasi WebSocket menentukan API yang membuat koneksi "socket" antara browser web dan server. Dengan kata sederhana: Ada koneksi persisten antara klien dan server dan kedua pihak dapat mulai mengirim data kapan saja.

Memulai

Anda dapat membuka koneksi WebSocket hanya dengan memanggil konstruktor WebSocket:

var connection = new WebSocket('ws://html5rocks.websocket.org/echo', ['soap', 'xmpp']);

Perhatikan ws:. Ini adalah skema URL baru untuk koneksi WebSocket. Ada juga wss: untuk koneksi WebSocket aman dengan cara yang sama seperti penggunaan https: untuk koneksi HTTP yang aman.

Melampirkan beberapa pengendali peristiwa secara langsung ke koneksi memungkinkan Anda mengetahui kapan koneksi dibuka, menerima pesan masuk, atau terjadi error.

Argumen kedua menerima sub-protokol opsional. Bisa berupa string atau array string. Setiap string harus mewakili nama sub-protokol dan server hanya menerima salah satu sub-protokol yang diteruskan dalam array. Sub-protokol yang diterima dapat ditentukan dengan mengakses properti protocol objek WebSocket.

Nama sub-protokol harus berupa salah satu nama sub-protokol yang terdaftar di registry IANA. Saat ini hanya ada satu nama sub-protokol (sabun) yang terdaftar pada Februari 2012.

// When the connection is open, send some data to the server
connection.onopen = function () {
connection.send('Ping'); // Send the message 'Ping' to the server
};

// Log errors
connection.onerror = function (error) {
console.log('WebSocket Error ' + error);
};

// Log messages from the server
connection.onmessage = function (e) {
console.log('Server: ' + e.data);
};

Berkomunikasi dengan server

Segera setelah kita memiliki koneksi ke server (saat peristiwa open diaktifkan), kita dapat mulai mengirim data ke server menggunakan metode send('your message') pada objek koneksi. Fungsi ini dulunya hanya mendukung string, tetapi dalam spesifikasi terbaru, sekarang juga dapat mengirim pesan biner. Untuk mengirim data biner, Anda dapat menggunakan objek Blob atau ArrayBuffer.

// Sending String
connection.send('your message');

// Sending canvas ImageData as ArrayBuffer
var img = canvas_context.getImageData(0, 0, 400, 320);
var binary = new Uint8Array(img.data.length);
for (var i = 0; i < img.data.length; i++) {
binary[i] = img.data[i];
}
connection.send(binary.buffer);

// Sending file as Blob
var file = document.querySelector('input[type="file"]').files[0];
connection.send(file);

Server juga dapat mengirimkan pesan kepada kita kapan saja. Setiap kali hal ini terjadi, callback onmessage akan diaktifkan. Callback menerima objek peristiwa dan pesan sebenarnya dapat diakses melalui properti data.

WebSocket juga dapat menerima pesan biner dalam spesifikasi terbaru. Frame biner dapat diterima dalam format Blob atau ArrayBuffer. Untuk menentukan format biner yang diterima, setel properti binerType objek WebSocket ke 'blob' atau 'arraybuffer'. Format defaultnya adalah 'blob'. (Anda tidak perlu menyelaraskan parameter binerType saat mengirim.)

// Setting binaryType to accept received binary as either 'blob' or 'arraybuffer'
connection.binaryType = 'arraybuffer';
connection.onmessage = function(e) {
console.log(e.data.byteLength); // ArrayBuffer object if binary
};

Fitur lain WebSocket yang baru ditambahkan adalah ekstensi. Dengan menggunakan ekstensi, frame dapat dikompresi, multiplex, dll. Anda dapat menemukan ekstensi yang diterima server dengan memeriksa properti ekstensi objek WebSocket setelah peristiwa terbuka. Tidak ada spesifikasi ekstensi yang dipublikasikan secara resmi mulai Februari 2012.

// Determining accepted extensions
console.log(connection.extensions);

Komunikasi lintas asal

Sebagai protokol modern, komunikasi lintas asal ditaruh langsung ke dalam WebSocket. Meskipun Anda tetap harus memastikan hanya untuk berkomunikasi dengan klien dan server yang Anda percayai, WebSocket memungkinkan komunikasi antarpihak pada domain apa pun. Server memutuskan apakah akan membuat layanannya tersedia untuk semua klien atau hanya klien yang berada di kumpulan domain yang didefinisikan dengan baik.

Server proxy

Setiap teknologi baru memiliki serangkaian masalah baru. Dalam kasus WebSocket, ini adalah kompatibilitas dengan server proxy yang memediasi koneksi HTTP di sebagian besar jaringan perusahaan. Protokol WebSocket menggunakan sistem upgrade HTTP (yang biasanya digunakan untuk HTTP/SSL) untuk 'mengupgrade' koneksi HTTP ke koneksi WebSocket. Beberapa server proxy tidak menyukai hal ini dan akan memutus koneksi. Jadi, meskipun klien tertentu menggunakan protokol WebSocket, koneksi mungkin tidak dapat dibuat. Ini membuat bagian berikutnya menjadi lebih penting :)

Gunakan WebSockets sekarang

WebSocket masih merupakan teknologi baru dan belum diterapkan sepenuhnya di semua browser. Namun, saat ini Anda dapat menggunakan WebSocket dengan library yang menggunakan salah satu fallback yang disebutkan di atas setiap kali WebSocket tidak tersedia. Library yang menjadi sangat populer di domain ini adalah socket.io yang dilengkapi dengan klien dan implementasi server dari protokol serta menyertakan fallback (socket.io belum mendukung pengiriman pesan biner sejak Februari 2012). Ada juga solusi komersial seperti PusherApp yang dapat terintegrasi dengan mudah ke lingkungan web apa pun dengan menyediakan HTTP API untuk mengirim pesan WebSocket ke klien. Karena permintaan HTTP tambahan, akan selalu ada overhead tambahan dibandingkan dengan WebSocket murni.

Sisi server

Penggunaan WebSocket menciptakan pola penggunaan yang sama sekali baru untuk aplikasi sisi server. Meskipun stack server tradisional seperti LAMP didesain dengan siklus permintaan/respons HTTP, stack tersebut sering kali tidak dapat menangani koneksi WebSocket terbuka dalam jumlah besar. Menjaga koneksi dalam jumlah besar tetap terbuka secara bersamaan memerlukan arsitektur yang menerima konkurensi tinggi dengan biaya performa yang rendah. Arsitektur tersebut biasanya dirancang dengan berbasis threading atau disebut IO non-pemblokiran.

Implementasi sisi server

Versi protokol

Protokol kabel (handshake dan transfer data antara klien dan server) untuk WebSocket sekarang menjadi RFC6455. Chrome dan Chrome terbaru untuk Android sepenuhnya kompatibel dengan RFC6455 termasuk pengiriman pesan biner. Selain itu, Firefox akan kompatibel pada versi 11, Internet Explorer pada versi 10. Anda masih dapat menggunakan versi protokol yang lebih lama, tetapi hal itu tidak disarankan karena diketahui rentan. Jika Anda memiliki implementasi server untuk protokol WebSocket versi lama, sebaiknya Anda mengupgradenya ke versi terbaru.

Kasus penggunaan

Gunakan WebSocket kapan pun Anda membutuhkan koneksi yang benar-benar rendah dan mendekati realtime antara klien dan server. Perlu diingat bahwa hal ini mungkin melibatkan pemikiran ulang cara Anda membangun aplikasi sisi server dengan fokus baru pada teknologi seperti antrean peristiwa. Beberapa contoh kasus penggunaan adalah:

  • Game online multiplayer
  • Aplikasi obrolan
  • Ticker olahraga live
  • Memperbarui streaming media sosial secara realtime

Demo

Referensi