Devnot Dotnet Konferansı Macerası — Building Real Time Applications with SignalR

Herkese Merhabalar,

Ben Kardel Rüveyda Çetin. Sizlerle bu heyecan verici yolculuğu paylaşmaktan büyük mutluluk duyuyorum. Bu konferans benim için gerçekten önemli çünkü öğrencilik yıllarımdan beri katılmayı hedeflediğim bir konferanstı. Her defasında, bir gün benim de burada konuşmacı olabilir miyim acaba diye düşünürdüm. Ve işte 2023 yılı geldi, şu anda konferansa katılımcı olarak değil, konuşmacı olarak hazırlanıyorum. İnanın bana, hazırlık süreci hiç de kolay olmadı. Büyük bir topluluk önünde sunum yaparken insan daha da detaycı ve mükemmeliyetçi oluyormuş, bunu anladım. 🙂

Üstelik, yüksek lisans eğitimim, finallerim ve ödevlerim de bu konferansın zaman dilimine denk geldi. Bu nedenle son derece disiplinli ve odaklı bir şekilde çalışmam gereken bir döneme girdim. Konuşmamın başlığı ise “SignalR ile Gerçek Zamanlı Uygulamalar Geliştirmek”. Neden bu konuyu seçtim diye sorarsanız, şu anda Doğuş Teknoloji’de Kıdemli Yazılım Uzmanı olarak çalışıyorum. Lugado ürünümüzde yer alan Agent Panel’i için chat alanı geliştirmesi yaparken SignalR teknolojisini kullandığımız için sizlere de bu teknoloji ile ilgili detaylar içeren bir sunum hazırladım.

Şu an konuşmamın hazırlıklarına devam ederken,bir yandan sizler için tüm konuşmanın içeriğini barındıran bu makaleyi de hazırlamaya çalışıyorum. Konferansa katılanlar bilecek ki, bu makaleyi sunumum bittiği an paylaşıyor olacağım. Umarım herkes için faydalı bir makale olmuştur diyip lafı çok da uzatmadan başlayayım. 🙂

Giriş ve Gündem Maddelerinden Bahsetme

Bugün sizlere öncelikle biraz kendimden bahsedip WebSocket, WebSocket alternatifleri, SignalR’ın ne olduğu , Kullanım Alanları, Mimarisi, Hangi Senaryolara Uygun Olmadığı, Başlangıç Aşamasında Nelere İhtiyacımız Olduğunu, İleri Seviye SignalR Örneklerini, IOT’de nasıl kullanılabileceğini, benim de şu an çalıştığım ve SignalR kullandığımız ürün Lugado’dan bahsedip son olarak bir uygulama da gerçekleşirip sunumu tamamlamayı düşünüyorum.

Ben Kimim?

Ben Kardel Rüveyda Çetin. Yıldız Teknik Üniversitesi Matematik Mühendisliği 2018 yılı mezunuyum. Akabinde Yıldız Teknik Üniversitesi Bilgisayar Mühendisliği Tezsiz Yüksek Lisans programından mezun oldum. Bu yıl itibariyle ise gene Yıldız Teknik Üniversitesi Matematik Mühendisliği’nde tezli yüksek lisans programında eğitim ve öğretim hayatıma devam etmekteyim.

Son 2 senedir Doğuş Teknoloji’de Kıdemli Yazılım Uzmanı olarak çalışmaktayım. Daha öncesinde üç seneye yakın bir Kariyer.net geçmişim bulunuyor. Kendimi bildim bileli Full Stack olarak çalışıyorum. Backend tarafında C#.Net Teknolojileri ilgimi çekerken önyüz tarafında tarafı ile yakından ilgilenmeye çalışıyorum. Dil sempatizanı değilim, her dili öğrenmeye hevesli ve istekliyim ama dotnet ilk göz ağrım orası da ayrı mesele. 🙂

WebSocket Nedir?

  • Gerçek anlamda tokalaşma, selamlaşma, tebrik, anlaşma veya vedalaşmayı sembolize etmek için iki kişinin ellerini kavrayıp sıkması olarak tanımlanabilir. Bilgisayar biliminde tokalaşma, sunucunun clientlarla senkronize olmasını sağlayan bir süreçtir. El sıkışma yani handhsake, Web Socket protokolünün temel kavramıdır. Aslında son yıllarda bizi ceplerimizdeki telefonlara bağlayan şeylerin temelinde olabilir. Bir noktada istemsizce telefonumuzu kontrol ediyoruz,gerçek zamanlı bir şekilde bize ulaşan bir mesaj veya bir mail var mı diye? Aslında düşündüğümüzde WebSocketler hayatımızın her yerinde olmuş oluyor.
  • WebSoketler özetle; sunucular ve clientlar arasında iki yönlü bir iletişim olarak tanımlanır, yani her iki taraf da aynı anda iletişim kurar ve veri alışverişinde bulunur.

Web Soket Protokolünün Açıklaması

  • Bu protokol, sıfırdan tam çift yönlü bir iletişimi tanımlar. Web soketleri, masaüstü zengin işlevlerini web tarayıcılarına getirme konusunda bir adım öne çıkmaktadır. İstemci/sunucu(client/server ) web teknolojisinde uzun zamandır beklenen bir yenilemeyi temsil etmektedir.
  • Web Socket’in en büyük avantajı, tek bir TCP bağlantısı üzerinden iki yönlü iletişim (full duplex) sağlamasıdır.
  • Protokol detayına https://datatracker.ietf.org/doc/html/rfc6455. linkinden ulaşabilirsiniz.

Url

HTTP’nin http ve https gibi kendi şemaları vardır. WebSoket protokolü de URL modelinde tanımlanan benzer şemaya sahiptir.

Tarayıcı Desteği

Edge, Mozilla, Firefox, Google Chrome, Safari ve Opera gibi çeşitli tarayıcılar tarafından desteklenmektedir.

WebSocket Alternatifleri

Polling

  • İletimde var olan verilere bakılmaksızın periyodik istekleri gerçekleştiren bir yöntem olarak Periyodik istekler senkronize bir şekilde gönderilir.

Polling sürekli isteklerle veri alışverişi yaparken, WebSocket gerçek zamanlı ve verimli bir iletişim sağlar. WebSocket, daha hızlı ve daha verimli bir veri alışverişi sağlayabilirken, Polling daha basit ve daha yaygın olarak kullanılan bir yöntemdir.

Long Polling

  • Adında da anlaşılacağı gibi, polling’e benzer bir teknik içerir.
  • Client ve Server, bazı veriler alınana veya zaman aşımı gerçekleşene kadar bağlantıyı aktif tutar.
  • Bağlantı bazı nedenlerden dolayı kesilirse, istemci baştan başlayabilir ve sıralı istek gerçekleştirebilir.

Long Polling, Client’ın Server’dan güncellemeleri beklediği sürekli bir bağlantı sağlar. WebSocket ise kalıcı bir bağlantıda tam çift taraflı iletişim sağlar. WebSocket, daha verimli ve hızlı bir gerçek zamanlı iletişim yöntemi olarak kabul edilirken, Long Polling daha geleneksel bir teknik olup bazı ölçeklendirme zorluklarına sahip olabilir.

Streaming

  • Gerçek zamanlı veri iletimi için en iyi seçenek olarak kabul edilir.
  • Sunucu, gerekli veriler alınana kadar istemci ile bağlantıyı açık ve aktif tutar.

Bu durumda, bağlantının süresiz olarak açık olduğu söylenir. Akış, dosya boyutunu artıran ve gecikmeyi artıran HTTP headerlarını içerir. Bu önemli bir dezavantaj olarak düşünülebilir.

Streaming, büyük veri setlerini veya sürekli akış gerektiren durumları işlemek için kullanılırken, WebSocket daha çok interaktif ve gerçek zamanlı etkileşim gerektiren uygulamalarda tercih edilir.

Postback and Ajax

· AJAX, Javascript’in XmlHttpRequest Nesnesine dayanmaktadır.

· Asenkron Javascript ve XML’in kısaltılmış bir şeklidir.

· XmlHttpRequest Nesnesi, web sayfasının tamamını yeniden yüklemeden Javascript’in yürütülmesine izin verir. AJAX, web sayfasının yalnızca bir bölümünü gönderir ve alır.

AJAX’ın Web Sockets ile karşılaştırıldığında en büyük dezavantajları; HTTP başlıkları gönderirler, bu da toplam boyutu büyütür. İletişim yarı çift yönlüdür. Web sunucusu daha fazla kaynak tüketebilir.

HTML5

HTML5, web sayfalarının yapısını ve içeriğini tanımlayan bir markup dilidir. Sayfaların görüntülenmesi ve düzenlenmesi için kullanılır. Ancak, HTML5 tek başına gerçek zamanlı iletişim için doğrudan bir mekanizma sağlamaz. HTML5, kullanıcı arayüzü, medya oynatma ve diğer web özelliklerini sağlar. WebSocket ise gerçek zamanlı veri iletişimi için daha spesifik bir protokoldür ve HTML5’in bir parçası olarak kullanılabilir.

Neden WebSocket’e ihtiyaç duyarız?

1. Gerçek zamanlı iletişim için ihtiyaç: Geleneksel web protokolleri gerçek zamanlı iletişimi sağlamada yetersiz kalır.

2. Verimlilik: WebSocket’ler, gereksiz veri trafiğini azaltır ve daha iyi bir performans sunar.

3. Daha iyi etkileşim: WebSocket’ler, hızlı ve anlık veri alışverişine olanak tanır, bu da daha iyi bir kullanıcı deneyimi sağlar.

4. Çoklu platform desteği: WebSocket’ler, web tarayıcıları, masaüstü uygulamaları ve mobil uygulamalarda kullanılabilir.

SignalR Nedir?

  • Uygulamalarımıza Real Time fonksiyonellik kazandıran open source yani açık kaynak bir kütüphanedir.
  • Hem ASP.NET hem de ASP.NET Core uygulamalarımıza Real Time özellik kazandırır.
  • SignalR’ın altında yatan teknoloji biraz bahsettiğimiz WebSocket teknolojisidir. WebSocket, tek bir TCP üzerinden client ve server arasında iki yönlü bir iletişim sağlayan protokoldür. Bir yerde bir protokol geçiyorsa zaten kurallar bütünü vardır demektir.
  • SignalR 2011 yılında ortaya çıktı geliştirildi, 2013 yılında ise ASP tarafına katıldı. O yıllarda tüm browserlar WebSocket’i kullanmıyordu ve destek yoktu. Eğer ki browser WebSocket kullanmıyorsa SignalR kendi altyapısını kullanarak client server arası haberleşmeyi sağlıyordu.
  • Günümüzde ise eğer browser WebSocket protokolünü destekliyorsa WebSocket’i kullanır desteklemezse kendi altyapısını sağlar.
  • Asp.NET tarafında SignalR’ı sorunsuz bir şekilde kullanabilirsiniz. DotNet Core için ise 2.1 versiyonundan itibaren kullanmanız gerekir.
  • Real-time özellik ne demek peki ? Bir uygulamanın real time olması client ve serverın anlık olarak sürekli haberleşmesi anlamına gelir ve bu haberleşme karşılıklıdır. Buna en güzel örnek browserlarda çalışan chat uygulamalarıdır. Herhangi bir Facebook chat ortamında browser hiç yenilenmeden karşı tarafla haberleşiriz ve karşı kullanıcının mesajları anlık olarak geliyor. Bizim yazdığımız mesajlar da karşı tarafa anlık olarak gitmektedir. Bu işlem Real Time da yapılan en güzel örneklerdendir. Bunun yanı sıra canlı açık arttırma işlemleri de buna örnek verilebilir. Browser yenilenmeden anlık olarak eşyanın değeri değişiyorsa browser yenileenmeden görebilirsinz.
  • Bir monitoring işlemi de bunun için geçerli olabilir logları canlı olarak göstermek istiyorsanız ve burada da anlık olarak browserın yenilenmeden göstermek istiyorsanız real time uygulamayı kullanabilirsiniz.

Şimdi gelin detaylı olarak kullanım alanlarına bakalım

Chat Uygulamaları

  • Demin de bahsettiğimiz gibi kullanıcıların anlık olarak iletişime geçebilmelerini sağlayan chat uygulamalarında kullanılır.

Finansal Ticaret Uygulamaları

  • Finansal ticaret uygulamaları, yatırımcıları en son piyasa trendleri hakkında bilgilendirmek için gerçek zamanlı güncellemeler gerektirir. SignalR, yatırımcılara gerçek zamanlı güncellemeler sağlamak için kullanılabilir.

Live Dashboard

  • SignalR, veriler değiştikçe otomatik olarak güncellenen gerçek zamanlı gösterge tabloları oluşturmak için kullanılabilir. Bu, sistemdeki değişiklikleri izlemek için gerçek zamanlı güncellemelerin gerekli olduğu izleme uygulamalarında kullanışlıdır. Demomuzda da bunla ilgili bir çalışma gerçekleştireceğiz.

Real Time Gaming

  • Gerçek zamanlı oyun uygulamaları, oyuncuların birbirileriyle iletişim kurabilecekleri ve gerçek zamanlı güncellemeler alabilecekleri sürükleyici oyun deneyimi sağlayabilmek için SignalR’I kullanabilir.

İşbirliği Uygulamaları

  • Birden fazla kullanıcı arasında gerçek zamanlı işbirliği gerektiren uygulamalar SignalR’den faydalanabilir. Örnekler arasında belge düzenleme ve proje yönetimi uygulamaları yer alır.

Bildirimler

  • SignalR, sistemdeki güncellemeler, olaylar veya değişiklikler hakkında kullanıcılara gerçek zamanlı bildirimler göndermek için kullanılabilir. Örneğin, yeni bir sipariş verildiğinde veya yeni bir mesaj alındığında kullanıcılara bildirimler gönderilebilir.

Push Notification kısmında daha yaygın ve uygun olarak kullanılmaktadır.

SignalR Mimarisini Anlamak

  • Projeniz ASP.NET veya Dotnet Core projesiyse SignalR kütüphanesini kullanabilirsiniz ve Real time uygulama inşa edebilirsiniz.
  • Mesala bir node js ise Socket.IO kütüphanesini kullanabilirsiniz. Python üzerinden bir gelitşirme yapıyorsanız WebSockets adında kütüphaneyi kullanabilrsiniz.
  • Ham WebSocket ile de kodlama yapılabilir. Hazır ve test edilmiş bir kütüphane varken neden custom bir web uygulamasının çalışabilmesi için ekstra kod yazılsın? Tabi ihtiyaçlar dahilinde
  • SignalR’ın kalbinde HUB dediğimiz merkezi yapı bulunmaktadır. Client ile Server arasındaki haberleşme HUB tarafından gerçekleşir. HUB dediğimiz de bir clasttır.
  • SignalR server oluşturmak istediğinizde bu HUB classından miras alarak uygulamalarınızı geliştirmek gerekecek.
  • Genel bir chat uygulamasında merhaba yazdığı zaman bu merhaba yazısı önce Hub’a gelir, Hub bu mesajı tüm clientlara dağıtıyor. Hangi clientlara dağıtır peki ? SignalR Hub’ın içindeki metota subscribe olmuş clientler bu mesajı alır. Bir chat uygualmasına girince odaya girmediğiniz zaman size bir mesaj gelir mi? Abone olmadığınız için gelmez. Bir Client’ın SignalR Server’ından mesajları alabilmesi için önce Subscribe olması lazım. Abone olduktan sonra başka bir client bir data yayınladığı zaman o datayı da alabilir. Subscribe sona ererse SignalR Hub’dan mesajları alamaz.
  • Client ile Server arasındaki iletişim bu hub üzerinden gerçekleşir.

Clients

İstemciler, gerçek zamanlı mesajlar almak ve göndermek için SignalR sunucusuna bağlanan kullanıcılar veya cihazlardır.

Transports

SignalR, istemci ve sunucu arasındaki bağlantıyı kurmak ve sürdürmek için çeşitli aktarımlar kullanır. Taşıma, WebSockets, Sunucu Tarafından Gönderilen Olaylar (SSE), Uzun Yoklama ve Sonsuza Kadar Çerçeve içerir.

Connections

Bir bağlantı, tek bir istemcinin SignalR sunucusuna olan bağlantısını temsil eder. Her bağlantı, sunucunun bağlantının durumunu izlemesini ve uygun istemciye mesaj göndermesini sağlayan benzersiz bir ID ile tanımlanır.

SignalR Server

SignalR sunucusu bağlantıların yönetilmesinden, mesaj yönlendirmelerinin yapılmasından ve istemciler ile sunucu arasındaki iletişim hattının yönetilmesinden sorumludur.

Yani özetle;

1. Client, SignalR’ı kullanarak sunucuya bağlanır.

2. Server tarafında, Hub sınıfı client iletişimini yönetir.

3. Client, hub yöntemlerini çağırarak sunucuya veri gönderir.

4. Server, hub yöntemlerini kullanarak client kısmına veri gönderir.

5. Client, gelen verileri dinler ve işler.

6. Bağlantı koparsa, SignalR otomatik olarak yeniden bağlanmayı dener.

SignalR Uygun Olmayan Senaryolar

SignalR, gerçek zamanlı web uygulamaları oluşturmak için kullanılan bir iletişim protokolüdür. Her ne kadar genel olarak esnek ve çeşitli senaryolara uygun olsa da, aşağıda SignalR için uygun olmayan bazı senaryoları bulabilirsiniz:

1. Düşük veri trafiği: SignalR, gerçek zamanlı iletişim için tasarlanmıştır ve sürekli olarak veri alışverişi yapar. Düşük veri trafiğine sahip uygulamalar için SignalR kullanmak gereksiz olabilir. Örneğin, basit bir haber sitesi, sadece kullanıcı sayfasını yenilemek için SignalR kullanmak yerine, AJAX veya diğer teknikleri tercih edebilir.

2. Tek yönlü iletişim: SignalR, temel olarak çift yönlü iletişimi destekler. Sunucu ve istemci arasında sürekli veri alışverişi yapmak için kullanılır. Eğer uygulamanızda tek yönlü iletişim yeterliyse, örneğin yalnızca sunucu tarafından istemcilere veri göndermek istiyorsanız, SignalR kullanmak gereksiz olabilir. Bunun yerine daha basit bir HTTP tabanlı API kullanmak daha uygun olabilir.

3. Düşük gecikmeye ihtiyaç duymayan uygulamalar: SignalR, gerçek zamanlı iletişim için tasarlandığından dolayı veri iletiminde bazı gecikmeler olabilir. Bu, bazı uygulamalar için kabul edilemez olabilir. Örneğin, finansal piyasalarda kullanılan yüksek hızlı ticaret sistemleri gibi uygulamalar, daha düşük gecikme sağlayan daha özel ve optimize edilmiş çözümler gerektirebilir.

4. Tek sunuculu uygulamalar: SignalR, birden fazla sunucuyla yüksek ölçeklenebilirlik ve yük dengelemesi sağlamak üzere tasarlanmıştır. Eğer uygulamanız tek bir sunucu üzerinde çalışacaksa ve ölçeklenebilirlik ihtiyacınız yoksa, SignalR kullanmak gereksiz olabilir. Bu tür durumlarda daha basit ve hafif çözümler kullanmak daha uygun olabilir.

Bu senaryolar SignalR için uygun olmayan durumları örneklemektedir. Bununla birlikte, her senaryo kendi gereksinimlerine bağlıdır ve uygulamanın doğasına ve ihtiyaçlarına bağlı olarak SignalR kullanılabilir veya tercih edilmeyebilir.

Başlangıç için SignalR

Her zor projelerin bile bir HelloWorld geçmişi vardır, bunu unutmamak lazım diyerek aşamalara başlayalım.

1- Hub, SignalR .Net Core’da bulunan bir kütüphanedir. Doğrudan projenize dahil edebilirsiniz.

2- ASP .Net Core Empty projesi oluşturun.

3- .Net Core 6.0 olabilir veya diğer sürümleri seçebilirsiniz.

4- Hubs Klasörü oluşturun ve hub sınıfı oluşturun. (MyHub vb olabilir. )

5- Hub classı Hub’dan türeyen bir class olduğunu unutmamak lazım.

6- Client’tan sonuç bekleyin, ReceiveMessage diye bir değer verdiğiniz diyelim ki tetikleyiciniz bu olsun.

7- Bu tetikleyici birlikte tüm clientlara mesaj gönderebilirsiniz.

8- Program.cs tarafında UseWebSockets() kullanıp WebSocket protokolünü belirlemek gerekir.

9- AddSignalR() middleware kullanarak Signal’r protokolünü belirtmek gerekir.

10- UseEndpoints alanını kullnarak da oluşturmuş oduğumuz Hub’ı belirtmeniz gerekiyor. Aksi halde client neye bağlanacağını bilemez.

11- HTML, CSS, JS, React.js, Angular.js vb. kullanabilirsiniz.

Örneğin jquery ile basit bir html de kullanım yaptığınızı düşünün;

  • Bunun için öncelikle signalr.minjs ve jquery.min.js kütüphanelerini dahil etmeniz gerekiyor. Bunu cdn yoluyla entegre etmeniz gerekir.
  • Jquery içerisinde document ready yapısını kullanarak sayfa tamamen yüklendiğinde çalışacak olan bir dinleyici tanımlayın.
  • HubConnectionBuilder kütüphanesi ile ( signlar dan gelen. ) bir signalr bağlantısı oluşturun.
  • Connection.start() Signalr bağlantısını çalıştırır ve sunucuyla iletişim kurmaya hazır hale getirir.
  • Connection. İnvoke() ile sunucuyla iletişim kurmak için SendMessageSync gibi bir hub yöntemini çağırabilirisniz.
  • Connection.On() ile Sunucudan gelen ReceiveMessage olayı dinlemiş olursunuz.

Advanced Durumlar

Load Balance

SignalR uygulamanızı birden fazla sunucuya dağıtmak ve yükü eşit olarak dengelemek için bir yük dengeleyici ( load balance ) kullanabilirsiniz. Örneğin, Azure’daki yerleşik yük dengeleyiciyi kullanabilirsiniz.

Caching

Sık erişilen verileri önbelleğe alarak SignalR performansını artırabilirsiniz. Örneğin, her istek için veritabanı sorgularını azaltmak için kullanıcı oturum bilgilerini önbelleğe alabilirsiniz.

Database Optimization

SignalR uygulamanız bir veritabanı ile etkileşime giriyorsa, veritabanı optimizasyon tekniklerini kullanarak performansı artırabilirsiniz. Bu, indeksleme, sorgu optimizasyonu ve veritabanı sunucusu ayarlarını düzenlemeyi içerebilir.

Custom Hub Class

SignalR’da Hub sınıfını özelleştirebilir ve istemciler ile sunucu arasındaki iletişimi kontrol edebilirsiniz. Örneğin, hub yöntemlerine özel yetkilendirme kontrolleri ekleyebilirsiniz.

Communication with Different Protocols

SignalR varsayılan olarak WebSockets üzerinden iletişim kurar, ancak diğer protokolleri de kullanabilirsiniz. Örneğin, SignalR’ı Long Polling veya Server-Sent Events gibi protokollerle kullanabilirsiniz.

Kimlik Doğrulama/Yetkilendirme:

SignalR’ı kimlik doğrulama ve yetkilendirme süreçleriniz ile entegre edebilirsiniz. Örneğin JWT (JSON Web Token) tabanlı kimlik doğrulama sağlayabilirsiniz. (Bunla ilgili biraz sonra örnek vereceğim .)

Mikroservisler

SignalR’ı mikroseris mimarisi ile birleştirerek farklı mikroservisler arasında gerçek zamanlı iletişim sağlayabilirsiniz. Örneğin, bir oyun uygulamasında oyuncular arasında gerçek zamanlı etkileşimi kolaylaştırabilirsiniz.

Serverless

SignalR’ı sunucusuz mimarilerde kullanabilirsiniz. Örneğin, SignalR’ı Azure Functions veya AWS Lambda gibi sunucusuz hizmetlerde kullanarak ölçeklenebilir ve kolayca yönetilebilir gerçek zamanlı uygulamalar oluşturabilirsiniz.

TTL/SSL Usage

HTTPS kullanarak SignalR iletişimini güvenli hale getirebilirsiniz. Bu, istemci ve sunucu arasındaki iletişimin şifrelenmesini sağlar.

Lugado ekibi olarak SignalR ile ilgili ileri seviyede örnekleri paylaşacağımız repoya linkten ulaşabilirsiniz.

Message Authentication ve Encryption

SignalR mesajlarını doğrulamak ve şifrelemek için özel işlemler uygulayabilirsiniz. Örneğin, mesajları RSA veya AES gibi algoritmalar kullanarak şifreleyebilirsiniz.

Authentication and Authorization( SignalR )

  • Bir SignalR uygulamasında, kimlik doğrulama ve yetkilendirme tipik olarak ara katman yazılımı ve Authorize özelliği kullanılarak gerçekleştirilir. Middleware, gelen isteklerin kimliğini doğrulamak ve yetkilendirmek için kullanılırken, Authorize özelliği, kullanıcı kimlik doğrulama ve yetkilendirme durumuna göre belirli SignalR hub’larına veya hub yöntemlerine erişimi kısıtlamak için kullanılır.
  • Tüm yöntemler için kimlik doğrulaması gerektirmek üzere hub sınıfına [Authroize] özniteliğini ekleyin ve tanımlanan ilkeye göre yetkilendirme gerektirmek üzere belirli yöntemlere [Authorize(‘policyName’)] özniteliğini ekleyin.
  • Son olarak, istemci tarafı JavaScript kodunda, geçerli kullanıcının erişim belirtecini almak için @microsoft/signalr paketi tarafından sağlanan AccessTokenFactory’yi kullanılabilir.

BONUS : Keycloak ile Authentication ve Authorization İşlemleri ( Lugado )

  • Keycloak, açık kaynaklı bir kimlik sağlayıcıdır ve SignalR ile kimlik doğrulama ve yetkilendirme yapısını entegre etmek için kullanılabilir.
  • Keycloak’ı indirin ve yerel bir sunucuda kurun veya bulut tabanlı bir Keycloak hizmeti kullanın.
  • Keycloak yönetim konsoluna erişin ve kullanıcılar, roller ve istemci (client) oluşturmak için gerekli ayarları yapın.
  • Keycloak’da her bir environmenta realm ismi verebilirsiniz. (preprod, prod vb.)
  • Uygulamalar için de realm altında client tanımlanabiliyor. (frontend,backend, chatty vb.)
  • Keycloak’ın tarafında bir endpoint bulunuyor. Bu endpoint tarafına istek atıldığında bize bir json dönüyor. Buradaki issuer kısmını almak gerekmektedir.
Örnek json
  • Realm’ın kendine ait keyleri de bulunuyor. Jwt Secret gibi alanları da realm altında bulabilirsiniz.
Örnek bir realm
  • opt.events’de ise gelen isteği alıp access_token query’sini çekip token varsa context içerisindeki token’ı setleyip atayabilirsiniz.
Örnek bir Program.cs
  • Son olarak da Hub’ın üstüne Authorize Annotation’ı ekleyip bitirdik. Artık bağlantıda token bakıp ona göre işlem yapabiliyoruz.

RabbitMQ Demo

  • Bir önceki örnekte Client olarak bir HTML,CSS, Javascript örneği üzerinden SignalR’a bağlanmıştık. Bu örnekte ise konsol uygulamalarından ya da farklı bir uygulamadan SignalR ‘a nasıl bağlantı sağlayabiliriz bunu göreceğiz. Burada Client’ımız bir konsol uygulamasıdır.
  • Bir adet Server bulunuyor. Clienttan istekleri alan bir Server gibi düşünebilirsiniz.
  • Server Request Response mantığında istek alıyor ve aldığı istekler neticesinde Client’a bir sonuç dönmektedir. Alacağa istekte bir API olduğunu düşünebilirsiniz. Bu istek üzerinde herhangi bir dosya , parser yapısı, word pdf dönüşü, image processing olabilir. Ağır bir işlem isteği yaptığını düşünün. Bu gibi bir durumda API tarafına bir ağırlık düşecektir. Bu gibi ölçeklendirme durumlarında mesaj kuyruk sisemleri kullanılabilir. Bu örnek kapsamında RabbitMQ kullanılmıştır.
  • Client’tan gelen bu istekler api’den mesaj kuyruk sistemine yani RabbitMQ ye düşecek şekilde tasarlanmıştır. Yapılacak olan operasyonları sıralı bir şekilde yapmaya çalışacak.
  • Örneğin, hosting firmalarında eğer yedek alınmaya çalışıyorsa “Hosting yedek almaya başlamıştır, pencereyi kapatsanız da yedek işlemi tamamlanınca size email gönderilecektir. “ şeklinde bir uyarı görmüşsünüzdür. Bu örnektede de client uygulamayı kapatsa Rabbitmq işlemi sıraya alıp ona mail gönderecektir.
  • Bir diğer önemli kısım olarak RabbitMQ’daki mesajları tüketecek olan Consumer’a ihtiyacımız bulunmaktadır. Consumer üzerinde RabbitMQ’ya gelen mesajları tek tek tüketilir. Consumer illaki tarayıcı uygulaması veya dotnet core uygulaması olmak zorunda değildir. Bu proje kapsamında konsol uygulaması kullanmıştır.
  • Konsol uygulaması ne zaman işini bitirirse asıl mevzu o zaman başlayacaktır. Bu kısımda serverda bir tane Hub ayarlandı. Normalde bu Hub’a client Subscribe olmuş olcak. Consumer da aynı şekilde bu Hub’a subscribe olacak. Consumer ne zaman işini bitirirse o zaman ilgili clienta real time da mesaj gönderimi gerçekleşmiştir..

Senaryo

  • Client mesaj gönderir: “Merhaba”.
  • Buradaki amaç Client’ın göndermiş olduğu mesajı ona mail olarak geri gönderme işlemini sağlamaktır.
  • Ancak buraya 1000 kişi aynı anda “Merhaba” yazıp istek gönderdiğinde, bu mesajları geri dönüş olarak aynı anda mail atmam çok mümkün olmaz. Hızlıca ölçeklendirme yapabilmek için RabbitMQ’ya gönderim gerçekleştirildi. Sonrasında RabbitMQ’daki mesajları Consumer tek tek işleyip mail atacak ve Hub sayesinde Client’ı real time olarak uyarıyor olacağız.
  • Client da Html ve Jquery ile yapılmış basit bir client uygulamasıdır.

RabbitMQ Konfigurasyonu ve Temel İşlemler

  • Herhangi bir uygulamada RabbitMQ ile iletişim kurmak için RabbitMQ.Client kütüphanesini yüklemeniz gerekir.
  • Yapmanız gereken işlem basit bir kuyruk sistemi oluşturmaktır ve bu kuyruğa mesaj göndermektir.
  • Bu proje kapsamında Cloud yapılandırması üzerinden gösterilmiştir. Normalde localde de kurulabilir. Veya docker containerda da kurabilirsiniz.
  • Cloud için https://www.cloudamqp.com/ sitesinden inceleyebilirsiniz. Giriş yaptığınzıda bu kısımda kullandığınız instanceler görülecektir.
  • RabbitMQ ye bağlantı için ConnectionFactory yapısı kullanılır. ConnectionFactory sayesinde bir factory oluşturulur. CreateConnection metotu ile ilgili connection sağlanır. ( IConnection türünde bir nesne döner. )
  • Factory tarafında Connection oluşturulurken Uri bildirilmesi gerekiyor. Bu Uri kısmını cloud’da oluşturduğunuz instance yapısından almanız gerekir. IModel türünden çalışılacak bu connection üzerinden createModel denilir ve kanal oluşturulmuş olur.
ConnectionFactory factory = new ConnectionFactory();
factory.Uri = new Uri("amqps://imevoimu:[email protected]/imevoimu");
using IConnection connection = factory.CreateConnection();

//Creating Channel 
using IModel channel = connection.CreateModel();
  • QueeDeclare fonksiyonu ile kuyruk oluşturulur. İlk parametre olarak kuyruğun ismi verilir. Birden fazla kuyruk olabilir, hangisinin tüketildiğini isminden yakalayacağız. QueueDeclare 2. Parametre olarak olası hata durumunda mesajlarınızı ayarlayabilirsiniz( durable ) , 3. durumda ise exclusive birden fazla kanalın bağlanıp bağlanmayacağı ile ilgilidir. Bir de autoDelete adında bir parametre vardır. Tüm mesajlar bitince kuyruğu otomatik imha etsin mi etmesin mi onu belirler.
  • Buradaki kuyruğa gönderirken RabbitMQ’da binary olarak gönderilmesi gerekiyor. Yani mesajı byte dizisine çevirmek gerekir. Sonrasında mesajı kullanabilmek için BasicPublish metotunu çağırmak gerekir. Burada öncelikle Exchange olarak Fanout Exchange kullanılmıştır. Hangi queue kullanılacaksa onun ismini vermek gerekir. İlgili queueye veri gönderilmiş olur.
            /Creating Queue
//durable messages for queue storage false and true ( durable )
// more channels connection ( exclusive )
// ending message after destroy channel ( auto delete )
channel.QueueDeclare("messagequeue",false,false,false);
string serializeData = JsonSerializer.Serialize(model);
//message to queue (binary type ) we can convert binary to byte
//exchange : behaviour
//routing : queue type
//body : binary format
byte[] data = Encoding.UTF8.GetBytes(serializeData);
channel.BasicPublish("","messagequeue",body:data);

return Ok();

Hub’ın Oluşturulması

using Microsoft.AspNetCore.SignalR;

namespace ServerApiExample.Hubs
{
public class MessageHub:Hub
{
public async Task SendMessageAsync(string message)
{
await Clients.All.SendAsync("receiveMessage", message);
}
}
}

Consumer ile RabbitMQ kuyruğundaki mesajları tüketmek.

  • Öncelikle RabbitMQ’ye bağlantı sağlanması lazım sonrasında mesajların RabbitMQ üzerinden kuyruğun tüketilmesi ve mesajların sıralı bir şekilde alınması gerekir. Mesajları aldıkça da email gönderme işleminin sağlanması gerekir.
  • Dolayısıyla bu işlem için API de olduğu gibi RabbitMQ client kütüphanesi yüklemek gerekir.
  • Consumer oluşturmak gerekiyor. Bu nedenle EventingBasicConsumer tüketici olarak tanımlanır. Bu consumer instance bir kanal isteyecektir. Bunu verdikten sonra Channel içerisindeki BasicConsume fonksiyonu çalıştırıp ilgili kuyruğun ismini vermek gerekir. autoAck parametresi kuyruktan alınan mesajın silinip silinmemesini sağlayan bir parametredir. True dersek tüktilen işlenen mesaj kuyruktak silinecektir. Sonrasında consumer da parametre olarak verilip işlem tamamlanır.
ConnectionFactory factory = new ConnectionFactory();
factory.Uri = new Uri("amqps://imevoimu:[email protected]/imevoimu");
using IConnection connection = factory.CreateConnection();
using IModel channel = connection.CreateModel();
channel.QueueDeclare("messagequeue", false, false, false);

EventingBasicConsumer consumer = new EventingBasicConsumer(channel);

channel.BasicConsume("messagequeue", true, consumer);
  • İlgili kuyruğa mesaj geldiğinde tüketmek için consumer.Received fonksiyonu kullanılmaıdır. Artık burada kuyruğa gelen mesajlar yakalanacak. Email operasyonunu ve Hub’ın tetiklenmesi de tam bu noktada gerçekleşiyor.
  • Kodlara linkten ulaşabilirsiniz.
consumer.Received += async (s, e) =>
{
//HubConnection connectionSignalR = new HubConnectionBuilder().WithUrl("https://localhost:7279/messagehub")
//.Build();

//await connectionSignalR.StartAsync();

//Email Operasyonları.
//e.Body.Span
string serializeData = Encoding.UTF8.GetString(e.Body.Span);
User user = JsonSerializer.Deserialize<User>(serializeData);


EmailSender.Send(user.Email,user.Message);
Console.WriteLine($"{user.Email} received");

//await connectionSignalR.InvokeAsync("SendMessageAsync", "Mail gönderildi.");
};

IOT ve SignalR

SignalR, IoT cihazları ve bir sunucu arasında gerçek zamanlı iletişim sağlamak için kullanılabilir. Örneğin, birden fazla sensörün bir sunucuya veri gönderdiği bir senaryo düşünün. Sunucu, bu verileri gerçek zamanlı olarak bir web veya mobil uygulamaya göndermek için SignalR’ı kullanabilir. Bu, uygulamanın sensör verilerini gerçek zamanlı olarak görüntülemesine ve meydana gelen değişikliklere yanıt vermesine olanak tanır.

1-) Her kamyon, konum verilerini düzenli aralıklarla sunucuya gönderen bir GPS sensörüne sahiptir.

2-) Sunucu GPS verilerini alır ve her bir kamyonun mevcut konumunu belirlemek için işler.

3-) Sunucu daha sonra SignalR kullanarak güncellemeleri harita uygulamasına gönderir ve her kamyonun mevcut konumunu iletir.

4-) Harita uygulaması güncellemeleri gerçek zamanlı olarak alır ve haritayı buna göre günceller.

5-) Kullanıcı tüm kamyonların konumunu harita üzerinde görüntüleyebilir ve hareket ettikçe güncellemeleri görebilir.

Lugado

Lugado, genel olarak chatbot geliştirmek için tasarlanmış bir üründür. Grup içi ve grup dışında birçok kişiye hizmet veriyoruz. Chatbot yanı sıra , chatbotu yönetbilecekleri bir yönetim paneli de tasarladık ve müşterilerin işlerini kolaylaştırkdı. Geçtiğimiz sene içerisinde müşterilerimize daha iyi bir deneyim sunmak amacıyla Lugado’ya bir agent paneli ekledik. Bu agent paneli, gerçek zamanlı iletişim sağlamak için SignalR teknolojisiyle entegre edilmiş bir chat uygulaması içermektedir. Bu sayede, müşterilerimizle hızlı ve etkileşimli bir şekilde iletişim kurabiliyoruz.

Demo

İllerden gelen anlık deprem sayılarını yansıttığımız bir proje yapmayı hedefliyoruz.

Veri tabanı işlemleri için

  • Entity Framework Core kullanıldı. Paket olarak Microsoft. Entity.FrameworkCore, Microsoft.EntityFrameworkCore.SqlServer ve Microsoft.EntityFrameworkCore.Tools eklendi.
  • Earthquake adında bir model oluşturuldu. Buradaki Ecity alanı benim tanımlanmış olduğum enum alanlardır. Tabloya City alanına buradaki Idleri basıyorum. Bir deprem sayısının belirtildiği count alanı mevcuttur.
  • AppDbContext alanında veri tabanı için gerekli işlemler gerçekleştirildi.

Hub

  • Bir Hubs klasörünün içerisinde EarthquakeHub olarak bir Hub oluşturuldu.
  • EarthquakeHub üzerinden chart besleniyor olacak.
  • Bir tane burada metot var GetEarthquakeHub, clientlar bu metotu çağrıdığı zaman o anda mevcut olan tüm earthquake sayılarını bir liste şeklinde alacaklar. Clientlar üzerinde tüm clientlara gidecek. SendAsync kullanıldıktan sonra “ReceiveEarthquake “ diyoruz ve bu da serviste yazdığımız metota gidiyor. Servisten Earthquake bilgilerini alıyor.

Controller

  • RandomEarthquakeCount buradaki metotta otomatik olarak random bir şekilde data kaydeden bir servis bulunuyor. 1 saniye durup tekrar data kaydeden , chartta real time olarak görüyor olacağız.

Client tarafı

  • Bir web projesi oluşturuldu.
  • Bu web projesinde EartquakeChartShow.cshtml adında bir yapı oluşturuldu.
  • Hub tarafına HubConnectionBuilder sınıfı ile bir bağlantı kuruldu.
  • Bağlantıdan sonra start ile birlikte bir bağlantı sağlandı.
  • connection.invoke() kullanıldı. EarthquakeHub’daki GetEarthquakeList’e bir invoke yapmam gerekecek.
  • Connection üzerinden connection.on() diyerek EarthquakeHub’daki ReceiveEarthquake’e abone olacağız o da bize chartlist’i döndü.
  • Google-chart’dan faydalanılmıştır.

Kodlara linkten ulaşabilirsiniz.

You may also like...

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir