Memperkenalkan WebSockets - Membawa Socket ke Web

Masalah: Koneksi klien-server dan server-klien dengan latensi rendah

Web sebagian besar telah dibuat berdasarkan paradigma permintaan/respons HTTP. Klien memuat halaman web, lalu tidak ada yang terjadi hingga pengguna mengklik halaman berikutnya. Sekitar tahun 2005, AJAX mulai membuat web terasa lebih dinamis. Namun, semua komunikasi HTTP diarahkan oleh klien, yang memerlukan interaksi pengguna atau polling berkala untuk memuat data baru dari server.

Teknologi yang memungkinkan server mengirim data ke klien tepat saat server mengetahui bahwa data baru tersedia telah ada sejak lama. Namanya antara lain 'Push' atau 'Comet'. Salah satu hack yang paling umum untuk menciptakan ilusi koneksi yang dimulai server disebut long polling. Dengan long polling, klien membuka koneksi HTTP ke server yang membuatnya tetap terbuka hingga mengirim respons. Setiap kali server benar-benar memiliki data baru, server akan mengirimkan respons (teknik lain melibatkan permintaan Flash, multipart XHR, dan yang disebut htmlfiles). Long polling dan teknik lainnya berfungsi dengan cukup baik. Anda menggunakannya setiap hari di aplikasi seperti chat Gmail.

Namun, semua solusi ini memiliki satu masalah: Solusi ini memiliki overhead HTTP, yang tidak membuatnya cocok untuk aplikasi dengan latensi rendah. Misalnya, game first-person shooter multipemain di browser atau game online lainnya dengan komponen real-time.

Memperkenalkan WebSocket: Membawa soket ke web

Spesifikasi WebSocket menentukan API yang membuat koneksi "soket" 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 membuka koneksi WebSocket cukup 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 https: yang digunakan untuk koneksi HTTP aman.

Dengan segera melampirkan beberapa pengendali peristiwa ke koneksi, Anda dapat mengetahui kapan koneksi dibuka, menerima pesan masuk, atau terjadi error.

Argumen kedua menerima sub-protokol opsional. Dapat 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 merupakan salah satu nama sub-protokol terdaftar di registry IANA. Saat ini hanya ada satu nama sub-protokol (soap) yang terdaftar sejak 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 memiliki koneksi ke server (saat peristiwa open diaktifkan), kita dapat mulai mengirim data ke server menggunakan metode send('your message') pada objek koneksi. Sebelumnya 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 mengirim pesan kepada kami 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, tetapkan properti binaryType objek WebSocket ke 'blob' atau 'arraybuffer'. Format default-nya adalah 'blob'. (Anda tidak perlu menyelaraskan parameter binaryType 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 yang baru ditambahkan ke WebSocket adalah ekstensi. Dengan menggunakan ekstensi, Anda dapat mengirim frame yang dikompresi, multipleks, dll. Anda dapat menemukan ekstensi yang diterima server dengan memeriksa properti ekstensi objek WebSocket setelah peristiwa terbuka. Belum ada spesifikasi ekstensi yang dipublikasikan secara resmi mulai Februari 2012.

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

Komunikasi lintas origin

Sebagai protokol modern, komunikasi lintas origin sudah terintegrasi langsung ke dalam WebSocket. Meskipun Anda tetap harus memastikan hanya berkomunikasi dengan klien dan server yang Anda percayai, WebSocket memungkinkan komunikasi antara pihak di domain mana pun. Server memutuskan apakah akan menyediakan layanannya untuk semua klien atau hanya klien yang berada di kumpulan domain yang ditentukan dengan baik.

Server proxy

Setiap teknologi baru memiliki serangkaian masalah baru. Dalam kasus WebSocket, 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 memutuskan koneksi. Dengan demikian, meskipun klien tertentu menggunakan protokol WebSocket, koneksi mungkin tidak dapat dibuat. Hal ini membuat bagian berikutnya menjadi lebih penting :)

Menggunakan WebSocket sekarang

WebSocket masih merupakan teknologi baru dan belum sepenuhnya diterapkan di semua browser. Namun, Anda dapat menggunakan WebSocket saat ini dengan library yang menggunakan salah satu penggantian yang disebutkan di atas setiap kali WebSocket tidak tersedia. Library yang telah menjadi sangat populer di domain ini adalah socket.io yang dilengkapi dengan implementasi protokol klien dan server serta menyertakan penggantian (socket.io belum mendukung pesan biner mulai Februari 2012). Ada juga solusi komersial seperti PusherApp yang dapat dengan mudah diintegrasikan ke lingkungan web mana 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 akan menciptakan pola penggunaan yang sama sekali baru untuk aplikasi sisi server. Meskipun stack server tradisional seperti LAMP dirancang berdasarkan siklus permintaan/respons HTTP, stack server tersebut sering kali tidak menangani koneksi WebSocket terbuka dalam jumlah besar dengan baik. Mempertahankan banyak koneksi terbuka secara bersamaan memerlukan arsitektur yang menerima konkurensi tinggi dengan biaya performa yang rendah. Arsitektur tersebut biasanya dirancang berdasarkan threading atau yang disebut IO non-blocking.

Implementasi sisi server

Versi protokol

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

Kasus penggunaan

Gunakan WebSocket setiap kali Anda memerlukan koneksi yang benar-benar memiliki latensi rendah dan hampir real-time antara klien dan server. Perlu diingat bahwa hal ini mungkin melibatkan pemikiran ulang tentang cara Anda mem-build aplikasi sisi server dengan fokus baru pada teknologi seperti antrean peristiwa. Beberapa contoh kasus penggunaan adalah:

  • Game online multiplayer
  • Aplikasi chat
  • Ticker olahraga live
  • Streaming media sosial yang diperbarui secara real-time

Demo

Referensi