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

SignalR ve WebSocket - 2

SignalR Kullanımı:

Genel olarak iletişim yöntemlerinden, websocket’ler ve signalR’dan bahsettikten sonra örnek bir proje ile kullanımını inceleyelim.

ASP.Net MVC 5 ve SignalR 2’yi kullanarak basit bir sohbet uygulaması ile signalR’ı anlatmaya çalışacağım.

Bunun için Visual Studio’ya ihtiyacımız var. Eğer Visual Studio kurulu değilse bedava versiyon olan Community Edition’ı buradan indirip kurabilirsiniz.

  1. Visual Studio’da New Project’i tıklayıp yeni bir web projesi oluşturuyoruz.

        2. MVC’yi seçiyoruz ve Change Authentication’ı tıklıyoruz.

       3. No Authentication’ı seçip OK butonunu tıklıyoruz.

    4. Projemiz oluştu ve kullanıma hazır. SignalR’ı projemizde kullanabilmek için SignalR kütüphanesini eklememiz gerekiyor.

Tools -> Nuget Package Manager -> Package Manager Console’ ı açıyoruz ve aşağıdaki kodu yazıp enter a basıyoruz.

install-package Microsoft.AspNet.SignalR

     5. Bu kod projemize signalR kullanmamız için gerekli javascript ve dll referanslarını ekliyor.

      6. Solution Explorer ekranında projeyi sağ tıklayıp Hubs adında yeni klasör ekliyoruz.

      7. Hubs klasörünü sağ tıklayıp Add -> New Item’ı tıklıyoruz ve Visual C# / Web / SignalR sekmesinde SignalR Hub Class ı seçiyoruz ve bir isim veriyoruz.

    8. ChatHub classına aşağıdaki metodu ekleyelim.

    9.  Startup.cs adında bir class oluşturalım ve içerisine aşağıdaki kodları yazalım.

   10. Controllers/HomeController.cs sınıfını açıp aşağıdaki metodu ekleyelim. Böylece adı Chat olan bir view dönmesini sağlıyoruz.

   11. Views/Home klasörüne sağ tıklayıp Add->View diyoruz ve adını Chat olarak giriyoruz.

      12. Chat view’ının içine aşağıdaki kodları yazıyoruz.

      13. Kodu çalıştırıp iki ve ya daha fazla farklı pencerede açarsanız, bir ekranda yazdığınız mesajın diğer bütün ekranlarda sayfayı yenilemeden göründüğünü farkedeceksiniz.

Kodun İncelenmesi:

Yazdığımız projede iki önemli geliştirme işi vardı. Birincisi merkezi koordinasyon için sunucuda bir hub geliştirdik, ikincisi de mesaj göndermek ve almak için SignalR jQuery kütüphanesini kullandık.

Bu noktada SignalR Hub’dan biraz bahsetmek gerek.

SignalR Hub:

İngilizce hub kelimesinin Türkçe karşılığı merkez, göbek demektir. Adından da anlaşılacağı üzere görevi de merkezde koordinasyonu sağlamaktır. Bu uygulamada istemcilerden gelen mesajları bütün diğer istemcilere göndermek gibi bir görevi var.

Buradaki önemli nokta hub javascriptini referans verdiğimiz halde fiziksel olarak projemizde böyle bir javascript dosyasının olmamasıdır. Bir çok kullanıcının kafası burada karışmaktadır.

Chat.cshtml dosyasında çağırdığımız bu referans scripti fiziksel olarak projede yoktur.

Tarayıcıda F12’ye basıp network trafiğini izlediğimizde böyle bir dosyanın istemciye geldiğini görüyoruz. Eğer bu dosya geliyorsa signalR düzgün çalışıyor demektir. Peki nasıl oluyor da sunucuda böyle bir dosya yokken istemciye gelebiliyor?

Cevabı basit: Auto-generetad proxies yani otomatik yaratılan proxyler. Proxy Türkçe’de vekil demek. Yani aslının yerine geçen anlamında. Peki neden vekil sınıflara ihtiyacımız var? Açıklayalım.

Sunucudaki Chathub.cs dosyasındaki kodumuz bu:

Otomatik yaratılıp istemciye gelen Proxy javascriptinin bir parçası da şu şekilde:

Chat.cshtml dosyasındaki Proxy classın referansı:

Chat.cshtml dosyasında serverdaki metodu çağırdığımız kod:

Buradaki püf nokta javascript kodundan sunucudaki c# metodunu çağırıyor olmamızdır. SignalR hub’ın yaptığı iş sunucudaki c# kodunu javascript koduna çevirmektir. İşte bu yüzden vekil deniyor. Yani aslı sunucudaki c# kodu, vekili de hubs javascript kodu. Biz yazdığımız javascript kodlarında direk sunucudaki metodu çağırmıyoruz da onun vekili olan javascript kodunu çağırıyoruz. O kod bizim sunucudaki metoda erişmemizde aracı  oluyor.

Sunucudaki kodu incelediğimizde adı send olan bir metodumuz var ve name ve message adında 2 adet string parametre alıyor. Buna karşılık oluşturulan signalr/hubs javascriptine baktığımızda yine böyle bir metot oluşturulduğunu ve böyle parametreleri olduğunu görüyoruz.

İsimlendirmelerdeki büyük-küçük harf farkına dikkatinizi çekmek istiyorum. Sunucudaki metotlar büyük harfle başlasa bile varsayılan olarak signalR javascript isimlendirmesini camel case’e göre yapar.

Örneğin classımız şöyle ise:

otomatik oluşturulan javascript kodumuz şöyle oluyor:

İstersek bu hub’ın adının nasıl yaratılacağını HubName attribute’ü ile belirleyebiliriz.

Bu durumda otomatik oluşturulan javascript kodumuz şöyle oluyor:

Otomatik yaratılan proxyler yerine otomatik yaratılmayan Proxy de kullanabiliriz. Fakat bu vekil sınıflarının otomatik yaratılmasının bir takım avantajları vardır. Sanki lokalde bir fonksiyon çağırır gibi kulanıyoruz ve bu bize kullanım kolaylığı sağlıyor. Bunun dışında Intellisense desteği sağlıyor. Sunucudaki metodun adını hatalı yazdığımızda bize istemci tarafında anında uyarı ve hata vermesi ise hatayı bulup düzeltmemizde ciddi bir zaman kazandırır.

Sunucuda yazdığımız hub sınıfının metotlarının istemci tarafından çağrılabilmesi için public olması gerektiğini unutmayalım.

SignalR Hub’ları açıkladığımıza göre şimdi kodlarımızı incelemeye devam edelim.

Uygulamamızda ChatHub adında bir class oluşturup onu Microsoft.AspNet.SignalR.Hub classından türettik. Class’ımızın hub olabilmesi için bu türetmeyi yapmamız gerekiyor. Bu sayede clientlere ve gruplara erişebiliyoruz.

Öncelikle signalR bağlantısı başlatılıyor:

Bu kod hub proxy’ye referans oluşturuyor:

İstemciler gönderenin adını ve mesajın içeriğini aşağıdaki kod ile sunucuya gönderiyor:

Sunucuda bu kodu çalıştırarak istemcilerdeki addNewMessageToPage javascript fonksiyonunu tetikliyor. Bu sayede gelen her mesajı bütün istemcilerin almasını sağlamış oluyor:

Bu kod ile istemcilere gelen mesaj ekrana yazılıyor ve kullanıcının görmesi sağlanıyor.

Uygulamamızı çalıştırdığımızda ilk önce kullanıcının ismini soracak:

Daha sonra iki farklı pencere açıp farklı isimler girdikten sonra birinden yazdığımız mesajın diğerinde de otomatik göründüğünü farkedeceksiniz. İstediğiniz kadar çok istemci açıp test edebilirsiniz. Mesajınız bütün kullanıcılara gidecektir.

Peki veri iletişimi istemcide nasıl görünüyor bir bakarsak:

İstemcide bağlantı websocket ile kurulmuşsa sunucuya gidip gelen verileri frame olarak görürüz.

H : Hub’ın adı

M : Metod Adı

A : Bu metoda gönderilen veriler, parametreler

Peki bağlantının websocket ile kurulduğunu başka nasıl anlıyoruz?

“Transport=” yazan yerde iletişim protokolünün hangisi olduğu ve versiyonu yazıyor. Bunu ayrıca http header’ında da görmek mümkün.

Sonuç:

Öncelikle web üzerinden iletişim yöntemlerini ve kısaca çalışma mantıklarına bir göz attık.

Daha sonra websocket ve signalR hakkında genel bilgiler verdikten sonra signalR’ın otomatik protokol seçimini nasıl yaptığına baktık.

Son olarak da örnek bir chat uygulaması ile signalR kullanarak bir web uygulaması yaptık ve bu uygulamayı çalıştırarak websocket ile verilerin nasıl gidip geldiğini inceledik.

Websocket protokolünün IETF tarafından oluşturulmuş standartına buradan ulaşabilirsiniz.

Bu makale ile signalR’ın gerçek zamanlı uygulama geliştirmek için bir kütüphane olduğunu ve bunu gerçekleştirmek için nasıl bir altyapı kullandığını anlatmaya çalıştım. Nasıl hub class’ı oluşturacağımızı, bu hub’a nasıl mesaj gönderip alacağımızı gördük.

Daha detaylı bilgi için:

Selçuk CİRİT