Azure Servis Bus Üzerinde SignalR Scale
Selamlar;
Bugün signalR kullanan bir projeyi, birden çok sunucu üzerinden yayımlarsak ne gibi sorunlar yaşıyacağımızı ve bu gibi durumlar için Azure tarafında nasıl bir çözüm üretebileceğimizi tartışacağız.
Öncelikle aşağıdaki gibi Mvc bir web application oluşturalım. Aşağıda görülen robot, ekran üzerinde herhangi bir noktaya tıklandığında ilgili kordinat’a hareket eder.
HomeController:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
using Microsoft.AspNet.SignalR; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using System.Web; using System.Web.Mvc; namespace SignalR_Scale.Controllers { public class HomeController : Controller { // GET: Home public ActionResult Index() { ViewBag.ServerName = Request.ServerVariables["REMOTE_ADDR"]; return View(); } } } |
Index.cshtml: Sayfa üzerinde tıklanma işlemi yapılınca, ilgili x ve y yani (left ve top) kordinatları alınıp robot resminin bulunduğu div’in bu noktaya animasyonlu bir şekilde hareketi sağlanır.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
@{ Layout = null; } <!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width" /> <title>Index</title> <script src="~/Scripts/jquery-2.1.3.min.js"></script> <script> $(document).click(function (event) { var x = event.pageX - 100, y = event.pageY; $('div').animate({ top: y, left: x }, 1000); }); </script> </head> <body background="~/score4.jpeg"> <div id="content" style="position:absolute;"> <img src="~/robot.png" style="width:200px" /> </div> </body> </html> |
Şimdi robotun hareketini bu sayfa üzerinde olan tüm clientlar için yapalım. Bu nedenle öncelikle signalR’ın aşağıdaki paketi Nuget’den indirilir.
Startup.cs: Startup.cs’e aşağıdaki kod eklenir.
1 2 3 4 5 6 7 8 9 |
using Owin; public class Startup { public void Configuration(IAppBuilder app) { app.MapSignalR(); } } |
Index.cshtml’e aşağıdaki signalR kodları eklenir: Öncelikle MoveRobot signalR class’ına connect olunur. Sayfanın herhangi bir yerine tıklanınca, ilgili hareketin tüm clientlara bildirilmesi için server side’daki MoveObject() methodu tetiklenir.
messagehub.server.moveObject(x, y);
Ayrıca server side’dan tüm clientlara, ilgili hareketi push etmek için clien tarafta messagehub.client.moveRobot() function’ı tanımlanmıştır.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
@{ Layout = null; } <!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width" /> <title>@ViewBag.ServerName</title> <script src="~/Scripts/jquery-2.1.3.min.js"></script> <script src="~/Scripts/jquery.signalR-2.2.0.min.js"></script> <script src="~/signalr/hubs"></script> <script> var messagehub = $.connection.moveRobot; $(document).click(function (event) { var x = event.pageX - 100, y = event.pageY; $('div').animate({ top: y, left: x }, 1000); messagehub.server.moveObject(x, y); }); messagehub.client.moveRobot = function (x, y) { console.log("client.moveRobot x=" + x + " y=" + y); $('div').animate({ top: y, left: x }, 1000); } $.connection.hub.start().done(function () { console.log("hub.start.done"); }).fail(function(error) { console.log(error); }); </script> </head> <body background="~/score4.jpeg"> <div id="content" style="position:absolute;"> <img src="~/robot.png" style="width:200px" /> </div> </body> </html> |
HomeController.cs: Aşağıda ilgili MoveRobot hub class’ının kodları tanımlanmıştır.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
using Microsoft.AspNet.SignalR; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using System.Web; using System.Web.Mvc; namespace SignalR_Scale.Controllers { public class HomeController : Controller { // GET: Home public ActionResult Index() { return View(); } } public class MoveRobot :Hub { public async Task MoveObject(int x, int y) { await Clients.All.moveRobot(x, y); } } } |
Şimdi uygulamayı Azure’a adım adım publish edelim.
1.Adım Publish Web’den Microsoft Azure Websites seçilir.
2.Adım: Azure hesabı ile login olunur.
3. Adım: New button’una basılarak, Azure üzerinde yeni bir website oluşturulur.
4.Adım: Yeni oluşturulacak Websitesinin adı ve oluşturulacağı bölgesi belirlenir.
5.Adım: Uygulama publish edilir. Ve böylece yayına alınır.
Şimdi signalrscale uygulamamızı aşağıdaki gibi Azure üzerinde SHARED tab’ından 6 sunucuya Scale edelim.
Aşağıdaki videodan da anlaşıldığı gibi Azure üzerindeki bir web application olan signalrscale projesi ilk önce SHARED tab’inden 6 sunucuya dağıtılarak Scale yapılıyor. Bu durumda uygulama 3 farklı sayfada çalıştırılınca, her sayfa farklı sunucuya gittiği için signalR çalışmıyor ve robot bir sayfada hareket ederken diğer sayfalarda duruyor. Daha sonra Scale özelliği kapatılıp uygulama tek sunucudan yayımlanınca her sayfa aynı sunucuya düştüğü için signalR çalışıyor ve bir sayfada robot hareket edince diğer browserlarda da hareket ediyor. Şimdi sıra geldi yüksek trafikli bir web uygulamasında, yükü kaldırmak için scale yapıldığı durumlarda signalR’ın nasıl kullanılacağına.
SignalR için scale yapmanın 3 yolu vardır. Biz aşağıdaki bu yollardan Azure Servis Bus olanını tercih edeceğiz.
1-) Öncelikle Visual Studio 2015’de aşağıdaki gibi yeni bir Azure Cloude Service projesi yaratılır.
2-)Daha sonra bu cloud servis için aşağıdaki gibi bir ASP.NET Web Role atanır.
3-) SignalR ve SignalR.ServicesBus paketleri nuget’den indirilir.
Publish İşleminden Önce Azure’da Yapılması Gereken 3 Adım:
1-) Signalrservers adında bir cloud servis Azure tarafında publish sırasından önce yaratılmış ve WebRole1 projesi buraya publish edilmiştir.
En başta yukarıda yazılan kodlar WebRole1 Mvc projesine konur. Projenin son hali aşağıdaki gibidir.
2-) Bir de Azure’da publishden önce yukarıdaki signalrscale cloude service’in çalışacağı bir storage account yaratılır. Storage account ile bir blob, bir table, bir de queue servisi sağlanır.
3-) Şimdi sıra geldi yukarıdaki örnekte olduğu gibi esas backplane olarak çalışacak servis bus’ı yine publish’den önce Azure tarafında yaratmaya. Aşağıda bunun ile ilgili ekran görüntüsü bulunmaktadır. Web Role’lerden biri, Service Bus’ın Topic’ine publish yapar. Servis Bus backplane ‘ın üzerindeki topic de kendine bağlı tüm Web Role’lere(Subscribelarına) bunu iletir. Bu Web Roller de kendilerine bağlı tüm clientlara bu mesajı signalR dediğimz real time web yani websocket teknolojisini kullanarak iletirler. Böylece ilgili mesaj tüm clientlara iletilmiş olur.
Servis Bus yaratılırken Region’ı cloude servis ve storage account ile aynı Region yani bölgede olması önemlidir.
Şimdi sıra geldi servis bus yaratıldıktan sonra ilgili connection string’i projemizde tanımlamaya. Aşağıda görüldüğü gibi yaratılan servis bus’a ait connection string alınır. Daha sonra projemizde alttaki gibi startup.cs altında eklenir.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
using Microsoft.AspNet.SignalR; using Owin; using System; using System.Collections.Generic; using System.Linq; using System.Web; public class Startup { public void Configuration(IAppBuilder app) { // Any connection or hub wire up and configuration should go here string connectionString = "Endpoint=sb://signalrscale.servicebus.windows.net/;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=xxxxxxxxxxxxxxxxx"; GlobalHost.DependencyResolver.UseServiceBus(connectionString, "signalrscale"); app.MapSignalR(); } } |
Artık uygulamamızı Azure’a publish edebiliriz:
1-) Öncelikle Azure account’u girilir.
2-) Azure üzerinde Cloude Service oluşturulur. Region ülkemiz için North Europe seçilmelidir.
3-) Aşağıda görüldüğü gibi Production ortamı için signalRScale cloude servisi oluşturulur.
3.1-) Advanced sekmesinde oluşturulacak olan storage account gözükmektedir.
4-) En son adım yaratılacak olan cloude services, storage account gibi diğer tüm bilgilerin dökümü ve publish için onay adımıdır.
Publish işlemi bittikten sonra signalrscale cloude services’inin dash board’una gelindiği zaman Azure hesabında kaç core limitin olduğu görülebilir. Örneğin aşağıdaki durumda uygulama tek core’lu 20 makina üzerinden scale yapılabilir. Ayrıca sağda görülen Site Url bizim cloude servicemizin url adresidir.
Aşağıda görüldüğü gibi örnek amaçlı Scale sekmesinden sözde yoğunluktan dolayı 6 makina üzerine instance oluşturulmuştur.
Oluşturulan Servis Bus’ın TOPİCS sekmesindeki ilk topic’in detay ekran görüntüsü aşağıdaki gibidir. Örnek messages iletimleri ve requestler grafiksel olarak gösterilmiştir. Toplam 5 topic yani konu oluşturulmuştur. WebRole’ler bu 5 topic’e bağlıdır. Yeni bir robot hareketi olunca bunla ilgili mesajı, subscribe yani bu WebRole’lere bildirme işi topic’in görevidir.
Konu ile ilgili örnek video aşağıdadır. Örnekde olduğu gibi 6 makina üzerinde scale yapılmıştır. Bir client’da olan değişiklik yani robot hareketi, kordinat parametreleri ile birlikte mesaj olarak 6 farklı makina üzerinden tüm clientlara bildirilmekte ve ilgili değişiklik yani robotun konumu real time olarak tüm clientlarda değiştirilmektedir.
Azure gerçekten çok kapsamlı, tabiri caiz ise ucu bucağı olmayan bir okyanus gibidir. Bu örnek de biraz olsun Azure üzerinden servis bus, cloude servis ve storage account konularına deyinilmek istenmiştir. Mvc .Net bir uygulamanın nasıl publish edileceğini, cloude bir servisin nasıl scale yapılacağını, site url’in nerden okunacağını, akan trafiği servis bus’daki bir topic üzerinden nasıl monitoring edilebileceğini, azure account üzerindeki core limitinin ne anlama geldiğini, storage account ile cloude servis arasındaki ilişkiyi inceledik. Böylece signalR bir projeyi, 6 makina üzerine scale yaparak iş yükünü bu makinalar arasında bölüştürdük. Ve karşılaştığımız bu yoğun tırafiği en verimli şekilde atlattık.
Yeni bir makalede görüşmek üzere hoşçakalın.
Selamlar Hocam;
Çok kapsamlı ve çok güzel bir signalR görünümlü Azure yazısı olmuş. Emeğiniz belliki çok büyük. Önümüzdeki yazılarınızda Azure üzerine daha çok yazarsanız biz de sizin tecrubelerinizden daha çok faydalanabiliriz.
Selamlar hocam;
Harika bir makale olmuş. İlkin çözülmesi gereken sorunun anlatıldığı video. Sonra çözümü gösteren birbaşka video. Konuyu destekleyen resim ve açıklamalar. Ve tabiki kodlar. Cidden muhteşem olmuş.
Elinize sağlık hocam.
Elinize sağlık hocam.
Kodun aynısını yaptım. Ben bir kutu hareket ettirdim. Gerçekten çok güzel oldu. Çok teşekkürler.
Bu kadar zor konuyu bu kadar güzel anlattığınız için teşekkür ederim. Azure üzerine yazılarınızı iple çekiyorum.
İyi çalışmalar.
Merhaba Hocam, çok yararlı bir yazı teşekkür ederim. Azure Event Hub kullanarak belirli verilerin web sayfasında anlık olarak gösterilmesi ile ilgili bir uygulama yapabilirseniz çok memnun olurum. İyi çalışmalar.
Selamlar Uğur,
Şu an yazdığım makale tam da bunu konu üzerine:) Bir İş Görüşmesinde Detaylı İstenen Proje Bölüm2.
İyi çalışmalar.