ASP.NET Core 2.0 SignalR – Basit Chat

Selamlar arkadaşlar,

Bu makalede macOS Sierra işletim sisteminde, .Net Core 2.0 ile bir Mvc projesinde, signalR kullanarak basit bir chat uygulaması yazacağız. Öncelikle baştan belirteyim, .net Core için signalR kütüphanesi bu makale yazılırken halen “1.0.0-alpha2-final” versiyonunda bulunmaktadır.

Peki kısaca signalR nedir ? Real Time yani canlı işlemler yapılmak için kullanılan bir socket teknolojisidir. Örneğin bir web sayfasında, canlı maç skoru bilgisinin client’ın herhangi bir servisi ya da yapıyı dinlemeden hatta sayfa refresh olmadan değiştirilmek istendiğinde, kullanılabilecek teknolojilerden sadece biridir.

Öncelikle gelin .Net Core Mvc projemizi oluşturalım. İlgili kurulumlar yapıldıktan sonra : Bash ortamında “dotnet new mvc -o signalRCore” yazılarak ilgili proje yaratılır.

  • Oluşan Mvc projede “signalRCore.csproj” dosyası aşağıdaki gibi güncellenir. ==>”<PackageReference Include=”Microsoft.AspNetCore.SignalR” Version=”1.0.0-alpha2-final” />” dosyası eklenir. Kaydetme işleminden sonra VS Code’un sorduğu Restore işlemine izin verilir. Ya da “dotnet restore” komutu gerek olmasa da çalıştırılabilir.
  • <Folder Include=”wwwroot\scripts\” />” : Aşağıda görülen bu ekleme ile “.cshtml” sayfa üzerinde eklenecek script dosyalarına kısa yol verilmiş olunur.

 

HomeController.cs : Aşağıda görüldüğü gibi Index() action’ına hiçbir değişiklik yapılmadan ilgili View’ın gelmesi sağlanmıştır.

Chat: Hub class’ı : Hub “Microsoft.AspNetCore.SignalR” namespace’i altında bulunan, real time socket işlemlerinin yapıldığı signalR sınıfıdır.

  • OnConnectedAsync()” : Methodu ile, client sayfayı ilk açtığı an, Chat Hub sınıfına connect olunur ve tam bu esnada bir ConnectionID alınır. Aslında bu her bir client için tekil oluşan bir tanımlayıcıdır. İşte tam bu anda devreye giren method “OnConnectedAsync()” methodudur. Burada herbir client için unique oluşturulan ConnectionID alınıp, tekrar ilgili client’ın kendisine gönderilir. Kısaca bir client spesific bir başka client’a bir bildiri gönderecek ise, aynı bir mail adresi veya telefon numarası gibi bu connectionID’ye ihtiyaç duymaktadır.
    • Clients.Client” : SignalR sınıfına connect olan herhangi bir client’ı belirtmektedir.
    • Clients.Client(Context.ConnectionId)“: Spesifik olarak connect olan client’ı temsil etmektedir.
    • “.InvokeAsync(“SetConnectionId”,Context.ConnectionId)” : Methodu ile client tarafındakiSetConnectionId()function’ı tetiklenmiş ve parametre olarak, ilgili client’a ait “Context.ConnectionId” gönderilmiştir. Burası bence signalR’ın en büyük gücüdür. Tekrarlamak gerekir ise Server Side Taraftan ==> Client Side Tarafdaki bir Function() tetiklenmişti.
  • SendMessage(string message)“: Connect olan tüm clientlara yazlmış olan mesajın gönderilmesi için kullanılan methoddur.
    • “Clients.All”: Tüm clientları temsil etmektedir.
    • “Clients.All.InvokeAsync(“GetMessage”, message)” : Hub sınıfına bağlı olan tüm clientlara, front taraftaki “GetMessage()” function’ı, server side taraftan parametre olarak gönderilemek istenen string mesaj değişkeni ile tetiklenir. Client Side ==> Her bir client’ın açtığı browser ekranı anlamına gelmektedir.

Not : Alttaki resimde signalR için kodlar biraz eskide kalsa da, mantık hep aynıdır. SignalR kısaca, server side tarafdan client side tarafdaki bir function’ın çağrılmasıdır. Aynı şekilde client side taraftan, server side tarafdaki bir method da çağrılabilir. Ama bu zaten pek de alışık olmadığımız bir durum değildir :)

Startup.cs: Aşağıdaki gibi düzenlenir. Asp.Net Core’da en başta herşey ham hali ile başlar. Amaç performans ve gereksiz hiçbir nesnenin bulunmayışının istenmesidir. Bu neden ile :

  • ConfigureServices() methodunda gerekli tüm servisler burada tanımlanır.==> services.AddMvc() ve services.AddSignalR() methodları eklenerek, projenin bir Mvc projesi olması ve SignalR kütüphanesinin bu projede kullanılacağı tanımlanmıştır.
  • Configure() methodunda bir takım ayarlamalar yapılır.
    • app.UseStaticFiles() : Proje içinde static dosyaların kullanılması sağlanır(wwwroot altında). Örnek resim dosyaları,script dosyaları gibi..
    • app.UseMvc(routes => : Mvc routing tanımlamalarının yapıldığı yerdir.
    • app.UseSignalR(routes => : “chat” sınıfının SignalR sınıfı olarak “chat” adı ile tanıtıldığı yerdir ==>”routes.MapHub<Chat>(“chat”);

Program.cs : dotnet run” komutu çalıştırıldığında, uygulamanın ayağa kalktığı default port 5000‘dir. Bunun istendiği gibi değiştirildiği yer, uygulamanın ilk ayağa kalktığı Program.cs sınıfıdır.

  • void Main() : İlk çalıştırılan methoddur.
  • BuildWebHost() : İlgili methodda host işlemi ile web sayfası ayağa kaldırılırken ==> “UseUrls(“http://localhost:1453”) komutu ile 5000 default portu 1453 olarak değiştirilmiştir.

Index.cshtml: Genel mesajlaşma işleminin yapıldığı ekrandır.

  • Dikkat edilir ise artık signalR’da önceden kullandığımız magic script denilen “<script src=”/signalr/hubs”></script>” kullanılmamaktadır.
  • Signalr, kendi içerisinde artık Jquery’e ihtiyaç duymamaktadır. Yehuuu :) Aşağıda kullanılma nedeni,  custom kullanılan functionlardır. Kısaca signalR değil ben kullandım :)
  • Sayfanın başında signalR için gerekli client script yanda görüldüğü gibi eklenmiştir.==>”<script src=”scripts/signalr-client-1.0.0-alpha2-final.min.js”></script>
    • İlgili signalR script kütüphanesi “npm install @aspnet/signalr-client –save”  komutu ile indirilebilir.
    • npm install @aspnet/signalr-client” komutu ile ilgili kütüphane, golbal’e de indirilebilir. İlgili dosya globalde yandaki klasörden erişilebilir==>”/usr/local/lib/node_modules/@aspnet/signalr-client/dist/browser/signalr-client-1.0.0-alpha2-final.min.js“. Bu script dosyasının projede “wwwroot” altında “scripts” klasörü altına kopyalanması gerekmektedir.
  • let connection = new signalR.HubConnection(‘/chat’)“: signalR Chat hub sınıfına bağlanılır.
  • connection.on(‘GetMessage‘, data => {” : Client Side tarafda signalR için function’ın yeni tanımlama şekli budur. “GetMessage()” functionın da, kendisine server side’dan gönderilen mesajları “messageList” id değerine sahip textare’ya eklemektedir.
  • connection.on(‘SetConnectionId‘, data => {” : Client’ın ilk connect olması durumunda, server side tarafındaki “OnConnectedAsync()” methodunda, ilgili bağlanan user’ın browserında çağrılan client side functiondır. Yani, server side taraftan ==> client side tarafa doğru tetiklenen bir functiondır.
  • connection.start()” : Ilgili Chat hub sınıfına bağlanıldığı kısımdır. Bu işlmeden sonra “OnConnectedAsync” methodu tetiklenir ve yeni bağlanan user’ın client side tarafındaki SetConnectionId() function’ı tetiklenerek, yeni alınan ConnectionID konsola yazılır.
  • function SendMessage(){” : Bu functionda da client side taraftan ==> server side tarafa doğru bir tetikleme mevcuttur. Yazılan mesajın tüm clientlara gönderilmesi için server side taraftaki “SendMessage()” methodu, yazılan text parametresi ile birlikte tetiklenir. “textarea”‘daki text mesajın değerinin alınması için $ jquery kullanılmıştır. Yoksa artık signalR paketinin jquery’e ihtiyacı yoktur :)
  • $(document).ready(function() {” : Bu jquery methodunda, sayfa yüklemesi yani render işlemi tamamlandığı zaman, içine mesaj yazılan textarea’ya “keypress()” eventi ile bağlanılır. Bu işlemde eğer basılan tuş “e.which==13” ==> Enter ise “SendMessage()” methodu çağrılır. Yani ilgili mesaj tüm clientlara gönderilir.

Bu makalede kısaca, signalR socket’in .Net Core ile cross platformda nasıl kullanıldığını, kurulumunu ve yapılması gereken configuration işlmelerini, basit bir chat uygulaması üzerinde inceledik.

Geldik bir makalenin daha sonuna. Yeni bir makalede görüşmek üzere hoşçakalın. Proje kodlarına aşağıdaki linkden ulaşabilirsiniz.

Source Code : https://github.com/borakasmer/.NetCore-SignalR-Basic-Chat

Herkes Görsün:

Bunlar da hoşunuza gidebilir...

11 Cevaplar

  1. emre dedi ki:

    hocam teşekkürler güzel paylaşım olmuş

  2. Zekeriya dedi ki:

    Hocam selamlar,
    SignalR’ı çeşitli işlemlerde sıklıkla kullanıyorum, veri güncellemelerinde, login işlemlerinde yönetici tarafına mesaj göndererek vs. merak ettiğim chat uygulamasında kullanıcı bazlı işlem yapmak mümkünmüdür örneğin connectionId, sini aldığımız her kullanıcıya, kişi bazlı mesaj gönderme olanağı sunuyormu?
    Saygılar.

  3. Melih dedi ki:

    Hocam selamlar, öncelikle paylaşımlarınız için teşekkürler.
    Angular da browser üzerinden url den parametre gönderilmesini engelleyip sadece bir button ile routerLink aracılığıyla parametre nasıl gönderirim yardımcı olur musunuz ?

  4. abit kabak dedi ki:

    Merhaba hocam,
    asp.net core 2.1 ile signalr teknolojisini kullanmak istediğimde aşağıdaki gbi bir hata alıyorum.
    Error: Failed to start the connection. Error: No available transports found.
    ConsoleLogger.log @ signalr.js:1744
    (anonymous) @ signalr.js:1903
    step @ signalr.js:1816
    (anonymous) @ signalr.js:1797
    fulfilled @ signalr.js:1788
    Promise.then (async)
    step @ signalr.js:1790
    (anonymous) @ signalr.js:1791
    __awaiter @ signalr.js:1787
    HttpConnection.startInternal @ signalr.js:1851
    (anonymous) @ signalr.js:1845
    step @ signalr.js:1816
    (anonymous) @ signalr.js:1797
    (anonymous) @ signalr.js:1791
    __awaiter @ signalr.js:1787
    HttpConnection.start @ signalr.js:1839
    (anonymous) @ signalr.js:2347
    step @ signalr.js:2232
    (anonymous) @ signalr.js:2213
    (anonymous) @ signalr.js:2207
    __awaiter @ signalr.js:2203
    HubConnection.start @ signalr.js:2338
    (anonymous) @ chat:128
    signalr.js:1930 Uncaught (in promise) Error: No available transports found.
    at HttpConnection.createTransport (signalr.js:1930)
    at HttpConnection. (signalr.js:1884)
    at step (signalr.js:1816)
    at Object.next (signalr.js:1797)
    at fulfilled (signalr.js:1788)

    • borsoft dedi ki:

      Selam,

      Program.cs’e alttaki satırı ekleyip denermisin! “signalR” erişim yolunu ve bunun gibi diğer Url’leri de buna göre değiştirmeyi unutma.
      .UseUrls(“http://localhost:5000”)

      İyi çalışmalar.

  5. mehmet özbay dedi ki:

    Bora hocam signalr örnekleri hep client dan diğer client’a veya server’dan client’lara şeklinde.Ben webclient’dan winform server’a mesaj göndermek istiyorum nasıl yapabilirim acaba?Bunu yapmaktaki amacım kullanıcının istediği web sayfası üzerinden istediği yazıcıya direkt yazılacak veriyi gönderebilmek.

    • borsoft dedi ki:

      Selam Mehmet,
      O zaman DB, RabbitMQ veye Redis gibi bir microservis kullanarak bir channel’a print() komutunu gönderirsin. Bu channel’ı windows makinada da dinleyerek, istenen işlemi yapabilirsin.

      İyi çalışmalar.

Bir cevap yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir