ASP.NET Core SignalR, uygulamalara gerçek zamanlı web fonksiyonelliği eklemeyi kolaylaştıran açık kaynaklı bir kütüphanedir. Gerçek zamanlı web fonksiyonelliği, sunucu tarafı kodunun istemcilere anında içerik iletmesini sağlar. Bu bölümde ASP.Net Core tanıtıldığı için bu kütüphane seçilmiştir. Bu konu da ünlü olan diğer bir kütüphane Socket.IO’dur. Bu bölümde basit bir örnekle SignalR tanıtılacaktır.
SignalR nerelerde kullanılabilir:
- Sunucudan sık sık güncelleme gerektiren uygulamalar: Oyunlar, Sosyal Ağlar, Oylama, Açık arttırma, Haritalar…
- Monitoring (izleme) uygulamaları: şirket kontrol paneli, anlık satış güncellemeleri, seyahat uyarıları, borsa…
- İşbirlikçi uygulamalar: Beyaz tahta uygulamaları, takım toplantı uygulamaları
- Uyarı veren uygulamalar: Social network, email, chat, oyunlar…
SignalR, sunucudan istemciye uzak yordam çağrıları (RPC) oluşturmak için bir API sağlar. RPC’ler, istemcilerde sunucu tarafındaki .NET Core kodundan JavaScript fonksiyonlarını çağırır. ASP.NET Core için SignalR’nin bazı özellikleri:
- Bağlantı yönetimini otomatik olarak yürütür.
- Tüm bağlı istemcilere aynı anda mesaj gönderir. Örneğin, bir sohbet odası.
- Belirli istemcilere veya müşteri gruplarına mesaj gönderir.
- Artan trafiği idare etmek için dengeler.
İletişim
SignalR, gerçek zamanlı iletişimi yürütmek için çeşitli teknikleri destekler:
- WebSockets
- Server-Sent Events
- Long Polling
SignalR, sunucu ve istemci özellikleri dahilinde en iyi taşıma yöntemini otomatik olarak seçer.
Hubs
SignalR, istemciler ve sunucular arasında iletişim kurmak için hub’ları kullanır. Bir hub, bir istemci ve sunucunun birbirine yöntemleri çağırmasına izin veren yüksek seviyeli bir pipeline’dır. Güçlü bir şekilde yazılan parametreleri, model bağlamaya olanak tanıyan yöntemlere iletebilirsiniz. SignalR iki yerleşik hub protokolü sağlar:
- JSON’a dayalı bir metin protokolü
- MessagePack’i temel alan bir ikili protokol.
MessagePack genellikle JSON ile karşılaştırıldığında daha küçük mesajlar oluşturur. Eski tarayıcılar, MessagePack protokol desteği sağlamak için XHR seviye 2’yi desteklemelidir.
Hublar, istemci tarafı metodun adını ve parametrelerini içeren iletileri göndererek istemci tarafı kodunu çağırır. Metot parametreleri olarak gönderilen nesneler, yapılandırılmış protokol kullanılarak deserialize edilir. İstemci, istemci tarafı kodundaki adı bir metotla eşleştirmeye çalışır. İstemci bir eşleşme bulduğunda, metodu çağırır ve deserialize edilmiş parametre verisine geçer.
Diğer konular gibi bu konu da çok geniş bir konudur. Bu bölümde basit bir örnek ile gerçek zamanlı iletişim yapan bir uygulama geliştirilecektir. Diğer konuları merak ediyorsanız tıklayın.
05.01. Proje açma
Öncelikle bir klasör oluşturalım ve File -> Open Folder yaptıktan sonra yeni bir terminal açın.
1 2 |
dotnet new webapp -o SignalRChat code -r SignalRChat |
SignalR istemci kütüphaneleri indirmek için öncelikle LibMan aracını kuralım.
1 |
dotnet tool install -g Microsoft.Web.LibraryManager.Cli |
LibMan aracı üzerinden SignalR istemci tarafı kütüphanesini wwwroot klasörüne indirilelim.
1 |
dotnet tool install -g Microsoft.Web.LibraryManager.Cli |
05.02. SignalR Hub oluşturma
Bir hub, istemci-sunucu iletişimini yöneten yüksek seviyeli bir pipeline olarak hizmet eden bir sınıftır.
- SignalRChat proje klasöründe bir Hublar klasörü oluşturun.
- Hublar klasöründe, aşağıdaki kodla bir ChatHub.cs dosyası oluşturun.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
using Microsoft.AspNetCore.SignalR; using System.Threading.Tasks; namespace SignalRChat.Hubs { public class ChatHub : Hub { public async Task SendMessage(string user, string message) { await Clients.All.SendAsync("ReceiveMessage", user, message); } } } |
ChatHub sınıfı, SignalR Hub sınıfından miras alır.Hub sınıfı bağlantıları, grupları ve mesajlaşmayı yönetir. SendMessage yöntemi, bağlı herhangi bir istemci tarafından çağrılabilir.Alınan mesajı tüm istemcilere gönderir.SignalR kodu, maksimum ölçeklenebilirlik sağlamak için eşzamansızdır.
Starthub.cs dosyasına aşağıdaki satırları ekleyelim.
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 SignalRChat.Hubs; namespace SignalRChat { public class Startup { … public void ConfigureServices(IServiceCollection services) { … services.AddSignalR(); } public void Configure(IApplicationBuilder app, IHostingEnvironment env) { … app.UseSignalR(routes => { routes.MapHub<ChatHub>("/chatHub"); }); … } } } |
Bu sayede sunucu tarafı hazır.
05.03. SignalR İstemci tarafı
Pages\Index.cshtml Razor sayfasını ekleyelim.
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 |
@page <div class="container"> <div class="row"> </div> <div class="row"> <div class="col-6"> </div> <div class="col-6"> User..........<input type="text" id="userInput" /> <br /> Message...<input type="text" id="messageInput" /> <input type="button" id="sendButton" value="Send Message" /> </div> </div> <div class="row"> <div class="col-12"> <hr /> </div> </div> <div class="row"> <div class="col-6"> </div> <div class="col-6"> <ul id="messagesList"></ul> </div> </div> </div> <script src="~/lib/signalr/dist/browser/signalr.js"></script> <script src="~/js/chat.js"></script> |
- Ad ve mesaj için text bölümlerini oluşturup, işlemi aktive etmek için submit button’u ekledik.
- id=”messagesList” olan etikete SignalR hub’undan alınan mesajları gösteren bir liste oluşur.
- SignalR istemci tarafı Javascript dosyalarını bağladık. Şimdi chat.js’yi wwwroot klasöründeki js clasörü içine yaratalım ve aşağıdaki kodları ekleyelim.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
"use strict"; var connection = new signalR.HubConnectionBuilder().withUrl("/chatHub").build(); connection.on("ReceiveMessage", function (user, message) { var msg = message.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">"); var encodedMsg = user + " says " + msg; var li = document.createElement("li"); li.textContent = encodedMsg; document.getElementById("messagesList").appendChild(li); }); connection.start().catch(function (err) { return console.error(err.toString()); }); document.getElementById("sendButton").addEventListener("click", function (event) { var user = document.getElementById("userInput").value; var message = document.getElementById("messageInput").value; connection.invoke("SendMessage", user, message).catch(function (err) { return console.error(err.toString()); }); event.preventDefault(); }); |
Uygulamayı debug edin ve browser açılınca, aynı URL ile ikinci bir sayfa açın. Chat yapmaya başlayabilirsiniz 🙂