Derinlemesine yazılım eğitimleri için kanalımı takip edebilirsiniz...

Asp.NET MVC 5 ve SignalR İle Chat Uygulaması

Web yazılımlarında temel Server – Client haberleşmesi senkron yani eşzamanlı bir yapıdadır.Kullanıcının gönderdiği talep doğrultusunda sayfa Server’a gider, gerekli işlemler neticesinde sayfa oluşturulur ve cevap olarak Client’a gönderilir.Halk dilinde “sayfanın gidip gelmesi” olarak bilinen ve internet kullanan herkesin bildiği sayfa geçişlerinde ya da form işlemlerinde beklenilmesi aslında bu şekilde bir işlemsel süreçtir.

Eğer ki, Server – Client arasındaki haberleşme asenkron yani eşzamansız bir yapıda gerçekleştiriliyorsa bu web programlama dilleriyle gerçekleştirilemeyeceği için Ajax, JSon vs. gibi yan teknolojiler söz konusu olmalıdırlar.Bu teknolojiler sayesinde görsel ve işlevsel olarak esnek ve kullanıcılar açısından oldukça kullanışlı web yazılımları üretebilmekteyiz.Tabi yan teknolojilerle yapılmak istenen işin ağırlığına göre kod yazma ve prosedürel algoritmalar üretmede de bir o kadar çaba sarf etmekteyiz.

Bu yazımızda bahsedilen ya da benzer yan teknolojilere değinmeyeceğim.Gelişmiş teknolojinin getirdiği kolaylıklar yanında, beklenmeyen yapılardan bahsedeceğiz.Örneğin Ajax ile oluşturacağımız bir Chat uygulamasını, SignalR sayesinde beş dakikada yazabilmemizi sağlayan kütüphaneden bahsedeceğiz.

SignalR Nedir?
Web uygulamalarında, Server – Client haberleşmesini asenkron yapıda sağlayan bir kütüphanedir.Türlü türlü yapılarıyla göz dolduran bir FrameWork yapısıdır.”.NET” mimarisi için gerçek zamanlı bir web ortamı sağlar.Bağlı olan Client’lara gerçek zamanlı olarak veri geçişi sağlamak için kullanılan bir kütüphanedir.

Mekanizdamada çalışan “WebSockets” sunucusu eşliğinde, Client’ların Server’ı pool etmesi engellenir.Bu arada SignalR arada bir katman görevi görmektedir.Sunucu veya Client WebSockets desteklenmiyorsa diğer teknolojilere(polling dahil) FallBack yapar.

SignalR ile veride bir değişiklik olduğunda Server bunu Client ya da Client’lara haber vermektedir.

Http’nin Stateless yapısından kurtulmak için “WebSocket” ve “Long Polling” dışında “Forever Frame” ve “Server Sent Events” olarak iki teknik yapı daha sunmaktadır.

Forever Frame, eskimiş bir tekniktir.O yüzden burada bu tekniğe girmeye gerek yoktur.
Server Sent Events, Http protokolünü değiştirmeden browser üzerinden işlem gerçekleştirmektedir.

Peki Gerçek Zamanlı Veri Geçişine Neden İhtiyaç Duyarız?
Bu sorunun cevabını yaşadığınız sanal dünyada çok rahat bir şekilde görebilirsiniz.FaceBook ya da Twitter kullananlar bilirler ki, kendileri bir talep oluşturmadıkları halde bile güncellemeler ya da bildirimler sürekli gerçek zamanlı olarak canlı bir şekilde gözümüzün önünden akmaktadırlar.Kullanıcılar tarafından tetiklenme olmaksızın iletilen ya da güncellenen verilere genellikle “Push” adı verilmektedir.

SignalR’ı tanıttıktan sonra Asp.NET MVC 5 mimarisiyle SignalR kütüphanesini kullanarak Chat uygulamasının nasıl yapılacağına geçebiliriz.

Visual Studio ortamından boş bir Asp.NET MVC 5 projesi açalım.
SignalR’ı Asp.NET MVC 5 ile kullanabilmemiz için gerekli JavaScript ve .DLL dosyalarını projemize entegre etmemiz gerekmektedir.Bu dosyaları projemize ekleyebilmeniz için “Tools > Library Package Manager > Package Manager Console” kombinasyonunu takip etmelisiniz.
Asp.NET MVC 5 SignalR Chat Uygulaması 1
Karşımıza bir konsol(console) ekranı çıkacaktır.Bu konsol ekranına “Install-Package Microsoft.AspNet.SignalR” değerini yazıp “Enter” tuşuna basıyoruz.
Asp.NET MVC 5 SignalR Chat Uygulaması 2
Konsoldaki yaptığımız işlemler sonucu gerekli JavaScript ve .DLL dosyaları projemize yüklenmiş olacaktır.
Asp.NET MVC 5 SignalR Chat Uygulaması 3
Şimdi SignalR ile Chat uygulamamızın programatik kısmına geçebiliriz.
Ben projemize “ChatHub.cs” isminde bir “SignalR Hub Class” ekliyorum.Siz istediğiniz isimde de ekleyebilirsiniz.
Asp.NET MVC 5 SignalR Chat Uygulaması 4

“ChatHub.cs” isimli SignalR Hub Class sınıfımızın içeriği aşağıdaki gibi olacaktır.

    public class ChatHub : Hub
    {
        public void Send(string username, string message)
        {
            Clients.All.sendMessage(username, message);
        }
    }

Yukarıdaki kod bloğunu incelerseniz eğer, “Send” isimli metodu ekleyerek Chat anında sohbet akışını sağlayacak program parçacığını belirtmiş oldum.

Şimdi de “Startup.cs” isimli bir sınıf oluşturalım.

using Microsoft.Owin;
using Owin;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
[assembly: OwinStartup(typeof(ChatUygulamasi.Startup))]

namespace ChatUygulamasi
{
    public class Startup
    {
        public void Configuration(IAppBuilder App)
        {
            App.MapSignalR();
        }
    }
}

“Statup.cs” isimli sınıfımızın içeriğide yukarıdaki gibi olmalıdır.

Şimdi tek yapmamız gereken Controller sınıfı eklemek ve View dosyasını oluşturmak.
Ben “Home(Controller).cs” isimli bir Controller sınıfı ekliyorum ve içerisindeki “Index” Action’ının View dosyasını oluşturuyorum.

    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            return View();
        }
    }
@{Layout = null;}
<!DOCTYPE html>
<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>Index</title>
    <script src="~/Scripts/jquery-1.6.4.min.js"></script>
    <script src="~/Scripts/jquery.signalR-2.1.0.min.js"></script>
    <script src="~/SignalR/Hubs"></script>
    <script>
        $(function () {
            var chat = $.connection.chatHub;
            var $username = $('#txtUsername');
            var $message = $('#txtMessage');
            var $messages = $('#messages');
            $message.focus();
            chat.client.sendMessage = function (name, message) {
                $messages.append('<li><strong>' + name + '</strong>: ' + message + '</li>');
            };
            $.connection.hub.start().done(function () {
                $('#btnSendMessage').click(function () {

                    chat.server.send($username.val(), $message.val());

                    $message.val('').focus();
                });
            });
        });
    </script>
</head>
<body>
    <div>
        <label for="txtUserName">Kullanıcı: </label> @Html.TextBox("txtUsername")
        <br />
        <label for="txtMessage">Mesaj: </label> @Html.TextBox("txtMessage") <button id="btnSendMessage">Mesaj Yolla</button>
    </div>
    <div id="messages"></div>
</body>
</html>

Yukarıda gördüğünüz gibi View katmanında gerekli JavaScript kodlarımızı yazıp ayarladıktan sonra projemizi derleyip çalıştırabiliriz.

İşte Asp.NET MVC 5 ve SignalR Chat Uygulamasını bitirmiş olduk.Chat uygulamamızın kullanımını aşağıdaki videomuzdan daha net görebilirsiniz.

Hepinize iyi çalışmalar diliyorum…

Örnek projeyi buradan indirebilirsiniz.

Bunlar da hoşunuza gidebilir...

28 Cevaplar

  1. Emre dedi ki:

    eline sağlık güzel olmuş.

  2. Ekrem ÖZER dedi ki:

    Gencay hocam eline sağlık. Peki bunu asp.net ‘de yapmamız için farklı ne yapmamız gerekiyor. script taglari arasındaki kod asp.net de farklılık gösterir mi? Sanırım olay orada bitiyor.

    • Gençay dedi ki:

      Fark göstermez kardeşim.Uyarlama esnasında bir iki değişiklik olabilir.Bu konuya araya zaman girdiği için bayağı uzak kaldım.

    • Gençay dedi ki:

      Off, offf!!!Sormadan, etmeden bu lüzumsuz duyarlılığınızın üzerine yapacağım pek bişey yok.”Çalma” diyerek ithamda bulunup, yaptığınız sorgusuz sualsiz iftira üzerine yorumunuzu paylaşıyorum ki, millet zihniyetsizlik görsün.

    • sedat dedi ki:

      emek emektır kendını gelıştırme adına sızde bır yerlerden alıp sizi takıp edenler ıcın paylaşa bılırsınız hırsızlık olması ıcın bunu ılk yazan yanı merve hanım sızın dedıgınız yerde sızın soylemınızle calmış. bunu ılk yazan herkese acık sekılde paylaşmıssa calmak olmaz ama altınada not dusmek lazım surdan esınlenerek felan dıye sadece kolay gelsın basarılar hepınıze

      • Gençay dedi ki:

        Doğrusu haklısınız.Esinlenilen kaynak ne olursa olsun belirtilmesi etik açıdan doğrudur.Bunu yapmadık diye çalıntı diye ithamda bulunmak zorlayıcı bir ifade.Nihayetinde bu tarz durumlarda hatalar ya da gözden kaçırmalar olabilir.Ama “adam gibi” yaklaşım olmadıktan sonra hiç bir şeyin ne değeri ne kıymeti vardır.Benim yazılarımda onlarca site tarafından bire bir olarak kopyalanıp yayınlanmakta ve kaynak gösterilmemektedir.Haliyle bu tartışma, benim kendi yorumlarımla harmanladığım içeriklerimde kaynakça alanları oluşturma ihtiyacı hissetmemekten kaynaklanmaktadır.Kaynakça nedir biliyorum ama bu hususta daha dikkatli ve hasas olmamız gerektiğini, üsluplu ya da üslupsuz okuyucularımızın bildirimlerinden anlamış bulunmaktayım.

        Neyse bunları biz yazarlar kendi aralarımızda halledebiliriz…
        Siz okuyucular yeter ki alacağınızı alın, faydalanın…
        Gerisi kafidir.

  3. merve dedi ki:

    Çaldığınızı tarihlere bakarak anladım.
    https://mcansozeri.wordpress.com/2013/12/11/blog-post-asp-net-mvc-5-ve-signalr-ile-5-dakikada-chatmesajlasma-uygulamasi-yazmak/
    bu yazının tarihi 11 Aralık 2013 sizinki 2014, sormaya gerek görmedim, terbiyesizlik yaparak üste çıkmaya çalışmışsınız, buyrun bakalım bu yorumumu da yayınlayın görelim

    • Gençay dedi ki:

      Teşekkür ederim…Çoğu konu stabil örnekler üzerinden verilmektedir.Örneğin, bir programın ilk başlangıcına dünyanın %99’u Hello World diye başlayarak örneklendirmektedir ya da for döngüsü hakkında piyasada pek fazla farklı bir örneklendirme göremezsiniz.await, async komutları hakkında ne kadar farklı kurgular üzerine makaleler okuyabildiniz?Mahmut Can Bey, piyasada takip ettiğim yazarlardan olması ve onun yer yer kendisinin yazı stiline makalelerimde yer vermemi çalıntı olarak nitelendirmeniz terbiyesizliktir.Nihayetinde, bu makale direkt olarak kopyala – yapıştır mantığıyla yazılmamış, üzerine düşünülüp, benzer kurgu tekrardan yaratılarak, ortaya ilgili linktekiyle aynı kod yapısında şahsi yorumlarımla bu makale yazılmıştır.

      Her stil benim için farklı bir renk simgeliyorsa eğer o stili kendime modellemeyi bir şahsi gelişim ve kazanç olarak görmekteyim.Aksi taktirde benim sitem ve sitelerimin birebir kopyalarına internette karşılaşmanız da mümkündür.Lakin içerikleri özgün olarak yazıldığı sürece bu benim için bir gurur meselesidir.

      Yazdığınız mesajın arkasında durup dönüt yapmanız taktire şayandır.Amaç çakallık olmadığı sürece bu sitede her türlü istişareye yer vardır.Buyrun, birebir olarak yazdığınız dört mesajtan bir tanesini seve seve yayınlarım.

  4. özlem dedi ki:

    Merhaba,
    SignalR ile bulduğum örnek uygulamaların tümünde aynı cshtml üzerinde etkileşim bulunmakta. Bu kütüphaneyi kullanarak örneğin kullanıcı tarafından yapılan bir yorumun admin ekranında post back yapılmadan görüntülenmesini sağlayabilir miyim? Bu konuda bana önerebileceğiniz bir makale mevcut mu?
    Teşekkürler.

    • Gençay dedi ki:

      Merhaba Özlem Hanım,
      Bahsettiğiniz durumla ilgili kısa bir araştırma yaptım ama sonuç bulamadım.Bu konuda işlevsel bir kaynakla karşılaşırsam eğer size mail adresinizden geri döneceğim.

      İyi günler dilerim.

      • özlem dedi ki:

        Çok teşekkürler.

        • Serdar dedi ki:

          iki farklı view açarak aynı formu iki viewde kullanırsanız istediğiniz gerçekleşir. SignalR hub yapısını kullandığı için farklı sayfalarda aynı hub a ulaşmanız yeterli

  5. Ömer USTA dedi ki:

    merhaba, iyi günler benim signalR gereken bir projem var fakat internetteki bütün dersler videolar chat uygulaması üzerine ben bi grafik yapıcam chart benim grafikteki stünlarım 5 dakkada bir otomatik değişicek sayfa yenilenmeden lütfen yardımcı olurmusunuz.

  6. ahmet dedi ki:

    Merhaba, Session ile oturum kontrolü yaptığım bir projede, signalr ile online kullanıcılar arası mesajlaşmayı nasıl sağlarım.

  7. abdullah dedi ki:

    hocam iyi günler bu kütüphaneyi kullanarak veri tabanına saatini eklediğim veriyi sistem saatine eşit oldupu zaman sayfayı yenilemeden görüntüleyebilirmiyim… örnek proje verirmisiniz konu ile ilgili ? mail adresimden ulaşırsanız sevinirim

  8. hocam öncelikle anlatım için teşekkürler iki sorum olacaktı.
    [assembly: OwinStartup(typeof(ChatUygulamasi.Startup))] satırını yazmadan da uygulama çalışıyor bu satırın anlamı nedir? Soruyu sorma nedenim benim projemde uygulama WebApplication şeklinde değil Web Site şeklinde oluşturulmuş olması ve bu satırı yazmayarak WebSite seçeneğinde kullanmayı düşünmem.
    İyi çalışmalar.

  9. mesut dedi ki:

    merhaba signal r projeye bakarak vb.nete çevirmeye çalıştım ama başaramadım çok aradım ama vb.net signal r chat örnegi ve anlatımı yok basıt bir örnekle acaba vb.net çevirip anlatabılırmısınız amatör biri olarak cevabınızı bekiyorum c# kodlarını vb.net çevirdim ama çalışmadı kodlara bakarak problem nerde bulabılırmısınız

    • Gençay dedi ki:

      Merhaba,

      VB.NET syntax yapısına hakim olmadığım için ne yazık ki isteğiniz üzerine vakit ayıracak kadar zamanım bulunmamaktadır.

      Sevgiler…

  10. Yasin dedi ki:

    Sa hocam benım unıversıtede projem sıgnal r ve sıngal r ıle asp.net mvc ortamnda gercek zamanlı mesajlasma hızmetı bu konuda bana neler yapmam gerektıgını solermısnz?

  11. Ayşe Sayarı dedi ki:

    Merhabalar, böyle bir makaleyi kazandırdığınız için çok teşekkür ederim.

    Sadece şu dikkatimi çekti, okurken de, uygularken de, Clients.All.addNewMessageToPage fonksiyonu…

    WhatsApp gibi bir uygulama üzerinden gidersek, sadece Muhatap kişi için biz iletinin ulaşmasını isteriz. Tüm kullanıcılara gitmemesi için nasıl bir yol izlememiz gerekir ?

    Sanırım program, tüm Client lara bu iletiyi göndermekte….

  12. Ayşe Sayarı dedi ki:

    Merhabalar, ben Akif Tuncel Meslek lisesini yeni bitirdim ve kendi çabamla yazılım sektöründe ilerlemek için çaba gösteriyorum.
    Makaleniz zevklei okudum; Signal R teknolojisi üzerine deneyim sahibi değilim, sadece şunu danışmak istiyorum;

    Clients.User(ConnectionId).send(message); (bu doğru bir syntax mı)

    Dilim döndüğünce stackoverflow a sordum, bana verilen yanıtlar yüzeysel idi,

    Signal R nin kendine ait bir ConnectionUser tablosu olduğu, Start Hub esnasında bağlanan kullanıcı dolayısıyla oluşturulan ConnectionID nin Kendi database imde olan UserID ile birlikte tanıtılması gerektiği ancak bu şekilde

    Clients.User(UserId).send(message); sözdiziminin geçerli olacağı paylaşıldı ama,

    Start Hub esnasında nasıl ConnectionID yi yakalayabileceğim (ki esas sorum bu idi)
    daha sonra da Signal R nin ConnectionUsers tablosuna kendi database imdeki kullanıcı id si ile birlikte nasıl tanıtabileceğimden pek bahsedilmedi

    ConnectionUsers.Add(GencayBeyUserID, ConnectionID) gibi bir metod mu var anlayamadım açıkçası (bulamadım da bu saat oldu 5:00)

    Çok eşekkür ederim.

  13. borahan dedi ki:

    Merhaba Gençay hocam,
    Merak ettiğim ve bilmediğim için soruyorum. SignalR sadece chat uygulamalarında mı kullanılıyor. herkes chat uygulaması örneği vermiş. Mesala ne biliyim facebook tarzı bildirimler filan yapılamıyormu.

Bir cevap yazın

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