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 olarak adlandırılan paradigması üzerine kurulmuştur. Bir istemci bir web sayfasını yükler ve kullanıcı sonraki sayfayı tıklayana kadar hiçbir şey olmaz. AJAX, 2005 civarında web'i daha dinamik hale getirmeye başladı. Yine de tüm HTTP iletişimleri istemci tarafından yönlendiriliyordu. Bu da sunucudan yeni veriler yüklemek için kullanıcı etkileşimi veya düzenli yoklama gerektiriyordu.

Sunucunun, tam da yeni verilerin mevcut olduğunu bildiği anda verileri müşteriye göndermesini sağlayan teknolojiler uzun süredir kullanımdadır. Bunlar "Push" veya "Comet" gibi adlarla kullanılır. Sunucu tarafından başlatılan bağlantı yanılgısı oluşturmak için kullanılan en yaygın saldırı yöntemlerinden biri, uzun yoklama olarak adlandırılır. Uzun yoklamada istemci, sunucuya bir HTTP bağlantısı açarak yanıt gönderene kadar sunucuyu 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 htmldosyaları bulunur). Uzun anketler ve diğer teknikler çok işe yarıyor. Bunları Gmail sohbeti gibi uygulamalarda her gün kullanıyorsunuz.

Ancak, tüm bu geçici çözümlerle ortak bir sorun vardır: HTTP ek yükü taşımaları, düşük gecikmeli uygulamalara uygun olmalarını sağlamaz. Tarayıcıda çok oyunculu birinci şahıs nişancı oyunlarını veya gerçek zamanlı bileşeni olan başka bir online oyunu düşünün.

WebSocket ile tanışın: Web'e yuvalar getiriyoruz

WebSocket spesifikasyonu, web tarayıcısı ile sunucu arasında "socket" bağlantıları kuran bir API tanımlar. Kısaca söylemek gerekirse, istemci 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şlayın

Bir WebSocket bağlantısı açmak için WebSocket oluşturucuyu çağırmanız yeterlidir:

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

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

Bazı etkinlik işleyicilerin bağlantıya hemen eklenmesi, bağlantının ne zaman açıldığını, gelen iletileri veya bir hata olduğunu öğrenmenize olanak tanır.

İkinci bağımsız değişken isteğe bağlı alt protokolleri kabul eder. Bir dize veya dizeler dizisi olabilir. Her dize bir alt protokol adını temsil etmelidir ve sunucu, dizide geçen 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 otoritesindeki kayıtlı alt protokol adlarından biri olmalıdır. Şubat 2012 itibariyle kayıtlı yalnızca bir alt protokol adı (sabun) mevcuttur.

// 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ı kurar kurmaz (open etkinliği tetiklendiğinde), bağlantı nesnesindeki send('your message') yöntemini kullanarak sunucuya veri göndermeye başlayabiliriz. Eskiden yalnızca dizeleri destekliyordu ancak artık son spesifikasyonda ikili iletiler de gönderebiliyor. İkili program verilerini 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 istediği zaman ileti gönderebilir. Bu durumda onmessage geri çağırma özelliği etkinleşir. Geri çağırma, bir etkinlik nesnesi alır ve asıl iletiye data mülkü aracılığıyla erişilebilir.

WebSocket ayrıca en son spesifikasyondaki ikili programları da alabilir. İkili çerçeveler Blob veya ArrayBuffer biçiminde alınabilir. Alınan ikili programın biçimini belirtmek için WebSocket nesnesinin ikiliType özelliğini "blob" veya "arraybuffer" olarak ayarlayın. Varsayılan biçim "blob" şeklindedir. (Gönderme sırasında ikiliType 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'in yeni eklenen diğer bir özelliği uzantılardır. Uzantılar kullanıldığında, sıkıştırılmış, çoklu vb. kareler göndermek mümkündü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ış herhangi bir uzantı spesifikasyonu yoktur.

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

Kaynaklar arası iletişim

Modern bir protokol olarak, kökenler arası iletişim doğrudan WebSocket'e yerleştirilmiştir. Yine de yalnızca güvendiğiniz istemciler ve sunucularla iletişim kurduğunuzdan emin olmanız gerekirken, WebSocket herhangi bir alan adındaki taraflar arasında iletişim sağlar. Sunucu, hizmetinin tüm istemcilere mi yoksa yalnızca iyi tanımlanmış bir alan adları kümesinde bulunanlara mı açıklanacağına karar verir.

Proxy sunucular

Her yeni teknoloji bir dizi yeni sorunu 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 bunu beğenmez ve bağlantıyı keser. Bu nedenle, belirli bir istemci WebSocket protokolünü kullansa bile bağlantı kurmak mümkün olmayabilir. Bu, bir sonraki bölümü daha da önemli hale getiriyor :)

WebSockets'i bugün kullanın

WebSocket hâlâ genç bir teknoloji ve tüm tarayıcılarda tam olarak uygulanmadı. Bununla birlikte, WebSocket'i şu anda, WebSocket kullanılamadığında yukarıda bahsedilen yedeklerden birini kullanan kitaplıklarla kullanabilirsiniz. socket.io bu alanda oldukça popüler hale gelmiştir. Bu kitaplık, protokolün bir istemcisi ve bir sunucu uygulaması ile birlikte gelir ve yedekleri de içerir (socket.io, Şubat 2012'den itibaren ikili mesajlaşmayı henüz desteklememektedir). Ayrıca, istemcilere WebSocket mesajları göndermek için bir HTTP API'si sağlayarak herhangi bir web ortamına kolayca entegre edilebilen PusherApp gibi ticari çözümler de vardır. Ekstra HTTP isteği nedeniyle, yalnızca WebSocket'e kıyasla her zaman ekstra ek yük olacaktır.

Sunucu tarafı

WebSocket kullanmak, 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üne göre tasarlanmış olsa da çoğu zaman çok sayıda açık WebSocket bağlantısıyla iyi sonuç vermez. Aynı anda çok sayıda bağlantıyı açık tutmak için düşük performans maliyetiyle yüksek eşzamanlılık alan bir mimari gerekir. Bu tür mimariler genellikle iş parçacıkları çevresinde tasarlanır veya engellemeyen IO olarak adlandırılır.

Sunucu tarafı uygulamalar

Protokol sürümleri

WebSocket için kablo protokolü (el sıkışma ve istemci ile sunucu arasındaki veri aktarımı) artık RFC6455 oldu. En son Chrome ve Android için Chrome, ikili mesajlaşma da dahil olmak üzere RFC6455 ile tam uyumludur. Ayrıca, Firefox sürüm 11, sürüm 10 üzerinde Internet Explorer ile uyumlu olacaktır. Eski protokol sürümlerini kullanmaya devam edebilirsiniz, ancak güvenlik açığı olduğu bilindiği için önerilmez. 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 gecikmeli, neredeyse gerçek zamanlı bir bağlantıya ihtiyacınız olduğunda WebSocket kullanın. Bunun için, etkinlik sıraları gibi teknolojilere yeni bir ağırlık vererek sunucu tarafı uygulamalarınızı oluşturma şeklinizi yeniden değerlendirmeniz gerekebileceğini unutmayın. Bazı örnek kullanım alanları şunlardır:

  • Çok oyunculu online oyunlar
  • Sohbet uygulamaları
  • Canlı spor haber şeridi
  • Sosyal akışların gerçek zamanlı olarak güncellenmesi

Demolar

Referanslar