WebSockets ile Tanışın - Yuvaları Web'e Taşıyor

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

Web, büyük ölçüde HTTP'nin istek/yanıt paradigması etrafında inşa edilmiştir. Müşteri bir web sayfasını yükler ve kullanıcı bir sonraki sayfayı tıklayana kadar hiçbir şey olmaz. 2005 yılı 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şimini veya periyodik anketi gerektiriyordu.

Sunucunun, yeni verilerin mevcut olduğunu bildiği anda istemciye veri göndermesini sağlayan teknolojiler uzun zamandır kullanılmaktadır. Bu tür kampanyalar "Push" veya "Comet" gibi adlarla anılır. Sunucu tarafından başlatılan bağlantı yanılsaması oluşturmak için kullanılan en yaygın saldırılardan biri uzun süreli sorgulamadır. Uzun süreli sorgu sırasında istemci, sunucuya bir HTTP bağlantısı açar ve yanıt gönderilene kadar bu bağlantıyı açık tutar. Sunucu gerçekten yeni verilere sahip olduğunda yanıtı gönderir (diğer teknikler arasında Flash, XHR çok parçalı istekleri ve html dosyaları bulunur). Uzun süreli sorgu ve diğer teknikler oldukça iyi çalışır. Bunları Gmail sohbeti gibi uygulamalarda her gün kullanırsınız.

Ancak bu geçici çözümlerin tümü aynı sorunu paylaşır: HTTP'nin ek yükünü taşır. Bu da onları düşük gecikmeli uygulamalar için uygun hale getirmez. Tarayıcıda oynanan çok oyunculu birinci şahıs nişancı oyunları veya gerçek zamanlı bileşen içeren diğer online oyunlar bu kapsamdadır.

WebSocket ile tanışın: Yuvalar artık web'de

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

Başlarken

WebSocket bağlantısını, WebSocket kurucusunu çağırarak açabilirsiniz:

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

ws: işaretine 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ıları için de wss: kullanılır.

Bazı etkinlik işleyicilerini hemen bağlantıya eklemek, bağlantının ne zaman açıldığını, gelen mesajları alıp almadığını veya hata olup olmadığını bilmenizi sağlar.

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

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

// 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 kurma

Sunucuyla bağlantı kurduğumuzda (open etkinliği tetiklendiğinde) bağlantı nesnesinde send('your message') yöntemini kullanarak sunucuya veri göndermeye başlayabiliriz. Önceden yalnızca dizeleri destekleyen bu protokol, en son spesifikasyonda artık ikili mesajlar da gönderebiliyor. İkili veriler 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);

Aynı şekilde, sunucu bize herhangi bir zamanda ileti gönderebilir. Bu her gerçekleştiğinde onmessage geri çağırma işlevi tetiklenir. Geri çağırma bir etkinlik nesnesi alır ve asıl iletiye data özelliği aracılığıyla 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 sayesinde sıkıştırılmış, çoklu kanallı vb. kareler gönderilebilir. open etkinliğinden sonra WebSocket nesnesinin extensions mülkünü inceleyerek sunucu tarafından kabul edilen uzantıları bulabilirsiniz. Şubat 2012 itibarıyla henüz resmi olarak yayınlanmış bir uzantı spesifikasyonu yoktur.

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

Kaynaklar arası iletişim

Modern bir protokol olan WebSocket, kaynaktan kaynak iletişimi için özel olarak tasarlanmıştır. Yine de yalnızca güvendiğiniz istemci ve sunucularla iletişim kurduğunuzdan emin olmanız gerekir, ancak WebSocket herhangi bir alandaki taraflar arasında iletişimi etkinleştirir. Sunucu, hizmetini tüm istemcilere mi yoksa yalnızca iyi tanımlanmış bir dizi alanda bulunanlara mı sunacağına karar verir.

Proxy sunucular

Her yeni teknoloji yeni sorunlar getirir. WebSocket'te ise çoğu şirket ağında HTTP bağlantılarını yöneten 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 bunu beğenmez ve bağlantıyı keser. Dolayısıyla, belirli bir istemci WebSocket protokolünü kullansa bile bağlantı kurmak mümkün olmayabilir. Bu nedenle, sonraki bölüm daha da önemli hale geliyor :)

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'in kullanılamadığı durumlarda, yukarıda belirtilen yedeklerden birini kullanan kitaplıklarla WebSocket'i hemen kullanabilirsiniz. Bu alanda oldukça popüler hale gelen bir kitaplık olan socket.io, protokolün istemci ve sunucu uygulamasıyla birlikte gelir ve yedek seçenekler içerir (socket.io, Şubat 2012 itibarıyla henüz ikili mesajlaşmayı desteklemiyor). 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, yalın WebSocket ile karşılaştırıldığında her zaman ekstra ek yük olacaktır.

Sunucu tarafı

WebSocket'i kullanmak, sunucu tarafı uygulamalar için yepyeni bir kullanım şekli 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 çıkamaz. 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 engellenmeyen G/Ç olarak adlandırılan özellikler etrafında tasarlanır.

Sunucu tarafı uygulamalar

Protokol sürümleri

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

Kullanım alanları

İstemci ile sunucu arasında gerçekten düşük bir gecikmeye ve neredeyse gerçek zamanlı bağlantıya ihtiyacınız olduğunda WebSocket'i kullanın. Bu işlemin, sunucu tarafı uygulamalarınızı nasıl oluşturduğunuzu yeniden düşünmeyi ve etkinlik sıraları gibi teknolojilere yeni bir odaklanma gerektirebileceğini unutmayın. Bazı örnek kullanım alanları:

  • Çok oyunculu online oyunlar
  • Sohbet uygulamaları
  • Canlı spor akışları
  • Sosyal medya akışlarını gerçek zamanlı güncelleme

Demolar

Referanslar