WebSockets ile tanışın: Yuvaları web'e taşıma

Sorun: Düşük gecikmeli istemci-sunucu ve sunucu-istemci bağlantıları

Web, büyük ölçüde HTTP'nin istek/yanıt paradigması üzerine inşa edilmiştir. İstemci bir web sayfası yükler ve kullanıcı bir sonraki sayfayı tıklayana kadar hiçbir şey olmaz. 2005 civarında AJAX, web'i daha dinamik hale getirmeye başladı. Yine de tüm HTTP iletişimi istemci tarafından yönlendiriliyordu. Bu da sunucudan yeni veri yüklemek için kullanıcı etkileşimi veya düzenli yoklama gerektiriyordu.

Sunucunun yeni verilerin mevcut olduğunu bildiği anda istemciye veri göndermesini sağlayan teknolojiler uzun süredir kullanılmaktadır. Bunlar "Push" veya "Comet" gibi adlarla anılır. Sunucu tarafından başlatılan bir bağlantı yanılsaması oluşturmak için en yaygın kullanılan yöntemlerden biri uzun yoklamadır. Uzun yoklamada istemci, sunucuya bir HTTP bağlantısı açar ve sunucu, yanıt gönderene kadar bu bağlantıyı açık tutar. Sunucuda yeni veri olduğunda yanıt gönderilir (diğer teknikler arasında Flash, XHR çok parçalı istekler ve htmlfiles olarak adlandırılan dosyalar bulunur). Uzun yoklama ve diğer teknikler oldukça iyi çalışır. Bunları her gün Gmail sohbet gibi uygulamalarda kullanırsınız.

Ancak tüm bu geçici çözümlerin ortak bir sorunu vardır: HTTP'nin ek yükünü taşırlar. Bu nedenle, düşük gecikmeli uygulamalar için uygun değildirler. Tarayıcıda oynanan çok oyunculu birinci şahıs nişancı oyunlarını veya gerçek zamanlı bileşeni olan diğer online oyunları düşünün.

WebSocket ile tanışın: Soketleri web'e taşıma

WebSocket spesifikasyonu, bir web tarayıcısı ile sunucu arasında "soket" bağlantıları oluşturan bir API tanımlar. Basitçe ifade etmek gerekirse: İstemci ile sunucu arasında kalıcı bir bağlantı vardır ve her iki taraf da istediği zaman veri göndermeye başlayabilir.

Başlarken

WebSocket oluşturucuyu çağırarak WebSocket bağlantısı açabilirsiniz:

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

ws: simgesine dikkat edin. Bu, WebSocket bağlantıları için yeni URL şemasıdır. Güvenli HTTP bağlantıları için https: kullanıldığı gibi güvenli WebSocket bağlantısı için de wss: kullanılır.

Bazı etkinlik işleyicileri doğrudan bağlantıya ekleyerek bağlantının ne zaman açıldığını, gelen mesajları aldığını veya bir hata olduğunu öğrenebilirsiniz.

İkinci bağımsız değişken, isteğe bağlı alt protokolleri kabul eder. Bu, bir dize veya dize dizisi olabilir. Her dize bir alt protokol adını temsil etmelidir ve sunucu, dizideki alt protokollerden yalnızca birini kabul eder. Kabul edilen alt protokol, WebSocket nesnesinin protocol özelliğine erişilerek belirlenebilir.

Alt protokol adları, IANA kayıt otoritesinde kayıtlı alt protokol adlarından biri olmalıdır. Şu anda, Şubat 2012 itibarıyla kayıtlı yalnızca bir alt protokol adı (soap) vardır.

// 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);
};

Sunucuyla iletişim kuruluyor

Sunucuyla bağlantı kurulur kurulmaz (open etkinliği tetiklendiğinde), bağlantı nesnesindeki send('your message') yöntemini kullanarak sunucuya veri göndermeye başlayabiliriz. Eskiden yalnızca dize desteklenirken en son spesifikasyonda ikili mesajlar da gönderilebiliyor. İkili veri göndermek için Blob veya ArrayBuffer nesnesini kullanabilirsiniz.

// 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);

Sunucu da bize istediği zaman mesaj gönderebilir. Bu durum her gerçekleştiğinde onmessage geri çağırma işlevi tetiklenir. Geri çağırma işlevi bir etkinlik nesnesi alır ve asıl mesaja data özelliği üzerinden erişilebilir.

WebSocket, en son spesifikasyonda ikili mesajlar da alabilir. İkili çerçeveler Blob veya ArrayBuffer biçiminde alınabilir. Alınan ikili dosyanın biçimini belirtmek için WebSocket nesnesinin binaryType özelliğini "blob" veya "arraybuffer" olarak ayarlayın. Varsayılan biçim "blob"dur. (Gönderirken binaryType parametresini hizalamanız gerekmez.)

// 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
};

WebSocket'e yeni eklenen bir diğer özellik de uzantılardır. Uzantıları kullanarak çerçeveleri sıkıştırılmış, çoğullanmış vb. şekilde göndermek mümkün olacaktır. Sunucu tarafından kabul edilen uzantıları, açık etkinlikten sonra WebSocket nesnesinin uzantılar özelliğini inceleyerek bulabilirsiniz. Şubat 2012 itibarıyla henüz resmi olarak yayınlanmış bir uzantı spesifikasyonu yoktur.

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

Çapraz kaynak iletişimi

Modern bir protokol olan WebSocket, çapraz kaynak iletişimini doğrudan destekler. Yalnızca güvendiğiniz istemciler ve sunucularla iletişim kurmanız gerekse de WebSocket, herhangi bir alan adındaki taraflar arasında iletişime olanak tanır. Sunucu, hizmetini tüm istemcilerin mi yoksa yalnızca iyi tanımlanmış bir alan kümesinde bulunan istemcilerin mi kullanımına sunacağına karar verir.

Proxy sunucuları

Her yeni teknoloji, yeni sorunları da beraberinde getirir. WebSocket söz konusu olduğunda, çoğu şirket ağında HTTP bağlantılarına aracılık eden proxy sunucularla uyumluluk söz konusudur. WebSocket protokolü, bir HTTP bağlantısını WebSocket bağlantısına "yükseltmek" için HTTP yükseltme sistemini (normalde HTTP/SSL için kullanılır) kullanır. Bazı proxy sunucular bu durumu kabul etmez ve bağlantıyı keser. Bu nedenle, belirli bir istemci WebSocket protokolünü kullansa bile bağlantı kurmak mümkün olmayabilir. Bu nedenle, bir sonraki bölüm daha da önemli. :)

WebSocket'leri hemen kullanmaya başlayın

WebSocket henüz yeni bir teknolojidir ve tüm tarayıcılarda tam olarak uygulanmamıştır. Ancak WebSocket'i, WebSocket'in kullanılamadığı durumlarda yukarıda belirtilen yedeklerden birini kullanan kitaplıklarla kullanabilirsiniz. Bu alanda çok popüler hale gelen bir kitaplık, protokolün istemci ve sunucu uygulamasıyla birlikte gelen ve yedekler içeren socket.io'dur (socket.io, Şubat 2012 itibarıyla ikili mesajlaşmayı henüz desteklememektedir). Ayrıca, istemcilere WebSocket mesajları göndermek için bir HTTP API sağlayarak herhangi bir web ortamına kolayca entegre edilebilen PusherApp gibi ticari çözümler de vardır. Ek HTTP isteği nedeniyle, saf WebSocket'e kıyasla her zaman ek ek yük olacaktır.

Sunucu tarafı

WebSocket kullanımı, sunucu tarafı uygulamaları için tamamen yeni bir kullanım modeli oluşturur. LAMP gibi geleneksel sunucu yığınları HTTP istek/yanıt döngüsü etrafında tasarlanmış olsa da genellikle çok sayıda açık WebSocket bağlantısıyla iyi başa çıkamazlar. Aynı anda çok sayıda bağlantıyı açık tutmak, düşük performans maliyetiyle yüksek eşzamanlılık sağlayan bir mimari gerektirir. Bu tür mimariler genellikle iş parçacığı veya engelleyici olmayan G/Ç etrafında tasarlanır.

Sunucu tarafı uygulamalar

Protokol sürümleri

WebSocket için kablo protokolü (istemci ile sunucu arasında el sıkışma ve veri aktarımı) artık RFC6455'tir. Chrome ve Android için Chrome'un en son sürümleri, ikili mesajlaşma dahil olmak üzere RFC6455 ile tamamen uyumludur. Ayrıca Firefox 11. sürümle, Internet Explorer ise 10. sürümle uyumlu olacaktır. Eski protokol sürümlerini kullanmaya devam edebilirsiniz ancak güvenlik açıkları olduğu bilindiğinden bu sürümler önerilmez. WebSocket protokolünün eski sürümleri için sunucu uygulamalarınız varsa bunları en yeni sürüme yükseltmenizi öneririz.

Kullanım alanları

İstemci ile sunucu arasında gerçekten düşük gecikmeli, neredeyse gerçek zamanlı bir bağlantıya ihtiyacınız olduğunda WebSocket'i kullanın. Bu durumun, sunucu tarafı uygulamalarınızı oluşturma şeklinizi etkinlik sıraları gibi teknolojilere yeni bir odaklanmayla yeniden düşünmenizi gerektirebileceğini unutmayın. Bazı örnek kullanım alanları:

  • Çok oyunculu online oyunlar
  • Chat uygulamaları
  • Canlı spor şeridi
  • Anlık olarak güncellenen sosyal akışlar

Demolar

Referanslar