Kurumsal IT-Teknoloji Eğitimleri-Eğitim Takvimi

SignalR ve WebSocket - 1

Bağlantı Yöntemleri

Http protokolü request ve reply mekanizması üzerine kuruludur. İstemci (client, browser) tarafından sunucuya bir istek gelir (genellikle POST ya da GET), sunucu bu isteğe(HTML sayfası, resim ya da JSON verileri vs… ile) cevap verir ve istemci ve sunucu arasındaki bağlantı sonlandırılır. Bütün bir web bu temel üzerine kuruludur. Http protokolü bağlantısız protokol (connectionless protocol) olarak tanımlanır. Sunucuya bir istek gelmeden sunucu istemciye herhangi bir bilgi yada uyarı gönderemez. Webin bu yapısı masaüstü uygulamalarına göre bir dezavantajdır. Çünkü masaüstü uygulamalarında TCP üzerinden bir bağlantı kurulur ve sunucu ve istemci istediği zaman bu bağlantıyı başlatıp kapatabilir, mesaj ve bilgi alışverişinde bulunabilir. Yani 2 yönlü bir iletişim vardır.

Zaman içerisinde web’in bu dezavantajının üstesinden gelmenin ve bir şekilde sunucudan istemciye, istemciden istek beklemeden bilgi göndermenin çeşitli yolları geliştirildi. Bu yollar şöyledir:

  • AJAX Polling: Belirli bir zaman periyodunda sayfanın tamamının ya da bir kısmının yenilenmesi yöntemidir.
    • İstemci sunucudan http protokolü üzerinden bir istekte bulunur.
    • Sayfada çalışan bir javascript kodu ile düzenli bir aralıkta tekrarlayan şekilde sunucuya istek gönderilir.
    • Sunucudan alınan cevaplarla sayfanın tamamı ya da sadece bir bölümü yenilenir.

  • Ajax Long Polling:
    • İstemci sunucudan http protokolü üzerinden bir istekte bulunur.
    • Sayfada çalışan bir javascript kodu sunucudan veri isteğinde bulunur.
    • Sunucu bu isteğe hemen cevap vermez. Yeni veri olana kadar bekler.
    • Yeni veri olduğunda bu verileri istemciye gönderir.
    • Sunucudan alınan cevaplarla sayfanın tamamı ya da sadece bir bölümü yenilenir.
    • İstemci hemen arkasından sunucuya yeni bir istek gönderir ve bütün süreci yeniden başlatır.

Long polling devamlı açık olan tek bir iletişim kanalı üzerinden gerçekleşmez. Sadece sunucu cevabı geciktirir. Sunucu cevap verdiğinde bağlantı kapatılacağı için hemen arkasından istemci yeni bir istek göndererek yeni bağlantıyı açar. Her bağlantı açıp kapatmanın bir maliyeti olacağı için biraz gecikmeye sebep olur ve en ideal yöntem değildir.

  • HTML5 Server Sent Events (SSE):
    • İstemci sunucudan http protokolü üzerinden bir istekte bulunur.
    • Sayfada çalışan bir javascript kodu sunucu ile istemci arasında bir bağlantı oluşturur ve bekler.
    • Sunucu yeni veri olduğu zaman bu bağlantı üzerinden cevap döner.

Avantajı, sunucudan istemciye gerçek zamanlı iletişime olanak vermesidir. Bu sayede sunucu istediği zaman istemciye veri gönderebilir, istemciden istek gelmesini beklemek zorunda değildir.

Internet Explorer dışındaki bütün tarayıcılar tarafından desteklenir.

SSE ile farklı domain’deki bir sunucudan iletişim kurulamaz.

  • HTML5 Websockets:
    • İstemci sunucudan http protokolü üzerinden bir istekte bulunur.
    • Sayfada çalışan bir javascript kodu sunucu ile istemci arasında bir bağlantı oluşturur ve bekler.
    • Sunucu ve istemci iki taraflı olarak istedikleri zaman veri alışverişinde bulunabilirler.

Avantajı, sunucudan istemciye ve ya istemciden sunucuya gerçek zamanlı iletişime olanak vermesidir. Bu sayede sunucu istediği zaman istemciye veri gönderebilir, istemciden istek gelmesini beklemek zorunda değildir. İstemci de istediği zaman istek gönderebilir.

Websockects ile farklı domain’deki bir sunucu ile iletişim kurulabilir.

 

Bu yöntemlerin dışında bir de Forever Frame yöntemi vardır.

Forever Frame: Sadece Internet Explorer tarafından desteklenen bu yöntemde gizli bir IFrame yaratılır ve bu IFrame üzerinden sunucuya istek gönderilir. Sunucu istemciye devamlı script gönderir ve istemci aldığı scriptleri hemen çalıştırır. Bu sayede sunucudan istemciye tek yönlü gerçek zamanlı bağlantı sağlanmış olur. İstemciden sunucuya gönderilecek istekler için ayrı bir bağlantı kullanılır ve bu bağlantı standart html bağlantısıdır. Her gönderilecek veri parçası için yeni bir bağlantı oluşturulur.

Websockets:

Websockets, TCP bağlantısı üzerinden full-dublex iletişim kanalı sağlayan bir protokoldür. Bu protokol 2011 yılında IETF(Internet Engineering Task Force) tarafından standardize edildi. Her ne kadar webde kullanım için tasarlanmış olsa da herhangi bir client server uygulamasında da kullanılabilir.

İletişim TCP protokolü ve 80 numaralı port üzerinden kurulur. Bu sayede firewall gibi, web için olan 80. port dışındaki diğer portları kapatan uygulamalar tarafından engellenmemiş olur.

Websockets’i öne çıkaran nokta protokolün full-dublex olmasıdır. Yani iki yönlü iletişim başlatılıp devam ettirilebilir. Bu sayede http protokolündeki gibi sadece istemcinin istek göndermesini beklemeden sunucu da iletişimi başlatabilir ve ya her hangi bir zamanda bir değişiklik olduğunda bunu istemciye bildirebilir.

SignalR:

İlk versiyonu ocak 2013’te Microsoft tarafından çıkartılan, ASP.Net ile geliştirilen web sayfalarına gerçek zamanlı iletişim gerçekleştirmeyi sağlayan yazılım kütüphanesidir.

Tarayıcı Desteği:

(*17 Nisan 2015 itibariyle tarayıcı desteği)

Websockect html5 ile gelen bir özelliktir ve hala tam olarak bütün web tarayıcılar tarafından desteklenmemektedir. CanIUse.com web sitesinde hangi tarayıcılar ve versiyonlarında desteklenip desteklenmediğini kontrol edebilirsiniz.

SignalR’ın Otomatik Protokol Seçimi:

SignalR istemci ve sunucu arasındaki gerçek zamanlı iletişim gerçekleştiren protokollerin üzerinde onları sarmalayan bir katman gibi düşünülebilir. Bir signalR bağlantısı http protokolü ile kurulur ve sonra destekleniyorsa websocket üzerinden devam eder. SignalR için ideal iletişim protokolü websocket’tir. Çünkü websocket’ler sunucu hafızasını en verimli kullanan, en düşük gecikmeye sahip olan ve altında farklı özellikleri barındıran (full dublex iletişim gibi) bir yöntemdir. Fakat en sıkı gereksinmelere sahip olan teknolojidir aynı zamanda. Websocket için sunucunun Windows server 2012 ve ya Windows 8 işletim sistemine sahip olması ve sunucuda .Net Framework 4.5’in kurulu olması gerekmektedir. Bu gereksinmeler karşılanmıyorsa signalR diğer iletişim yöntemleri (ajax long polling gibi) ile bağlantıyı devam ettirir. SignalR’ın alt katmanları soyutlamasının en büyük avantajı websocket versiyonlarını takip etmek zorunda kalmıyor olmanızdır. SignalR güncellendikçe yeni versiyonları da otomatik destekleyecektir. Diğer avantajı da hangi protokolün desteklenip desteklenmediği ile ilgilenmenize ve farklı iletişim yolları için farklı kodlar yazmanıza gerek kalmaz. Seçimi kendisi otomatik yapacaktır.

Bu yüzden yeni bir proje yaparken direk websocket yerine signalR kullanmak kapsama alanınızı genişletecektir.

Peki signalR bu seçimi nasıl yapar. Aşağıdaki liste signalR’ın hangi iletişim yöntemini nasıl seçtiğini gösteriyor.

  1. Eğer browser Internet Explorer 8 ve altı ise long polling kullanılır.
  2. Eğer JSONP kullanılıyorsa (bağlantı başlatıldığında jsonp parametresi true olarak ayarlanmışsa) yine long polling kullanılır.
  3. Eğer cross-domain bağlantı (yani signalR sunucu tarafı sayfanın domaininde değil de başka bir domainde ise) aşağıdaki kriterler karşılanıyorsa websocket kullanılır.
    1. İstemci CORS (Cross-Origin Resource Sharing) destekliyorsa. Hangi istemcinin desteklediği bilgisine buradan bakabilirsiniz.
    2. İstemci websocket destekliyorsa.
    3. Sunucu websocket destekliyorsa

Eğer bu kriterlerden herhangi biri karşılanmıyorsa o durumda long polling kullanılır.

Cross-domain bağlantı sağlamak ile ilgili detaylı bilgiye buradan ulaşabilirsiniz.

  1. Eğer JSONP ayarlanmamışsa ve bağlantı cross-domain değilse ve istemci ve sunucu websocket’i destekliyorsa websocket kullanılır.
  2. İstemci ve ya sunucu websocket’i desteklemiyorsa, Server Sent Events (SSE) destekleniyorsa SSE kullanılır.
  3. Server Sent Events desteklenmiyorsa Forever Frame yöntemi kullanmayı dener.
  4. Eğer Forever Frame başarılı olmazsa long polling yöntemini kullanır.

Bağlantıyı başlatırken istersek bu otomatik seçimlerin sırasını belirleyebiliyoruz:

$.connection.hub.start({ transport: ['webSockets', 'longPolling'] });

Seçebileceğimiz yöntemler:

  • webSockets
  • foreverFrame
  • serverSentEvents
  • longPolling

Kullanım Yerleri:

  • Sohbet odaları,
  • Gerçek zamanlı formlar,
  • Dashboard gibi durum görüntüleme uygulamaları,
  • Bir işin tamamlanma durumunu gösteren uygulamalar,
  • Oyunlar,
  • Aynı anda düzenlenen dökümanlar,
  • Bildirimler gibi gerçek zamanlı uygulamalarda kullanılabilir. Bunlar en çok kullanılan örnekler olmakla beraber, çok çeşitli kullanım yerleri olabilir. Bütün istemcilere broadcast yapma imkanı vardır. Hızlı iletişim ve iletişimin sunucudan başlatılması gerektiği durumlarda, bir istemciden yapılan değişikliklerin diğer istemcilere anında yansıtılması gerektiği durumlarda özellikle tercih edilir.

Örneğin web arayüzünden cevabı uzun sürecek bir istek gönderilecek. Bütün sayfanın akışını engellemeden, kullanıcı arayüzde istediği şeyleri yapmaya devam eder. İşlem tamamlandığında sunucu istemcideki javascript kodunu çağırıp ekranda bildirim görünmesini sağlayabilir.  Ya da online bir oyunda bütün kullanıcı verilerinin senkronizasyonu için kullanılabilir.

Lisansı:

Temmuz 2011’den beri açık kaynak kodludur ve Apache2.0 lisansına sahiptir. (https://github.com/SignalR/SignalR)

Selçuk CİRİT