SelamünAleyküm, bu yazımızda geçtiğmiz Asp .Net Core SignalR 1 - Giriş yazımızda signalR'ı teorik olarak incelemiştik bu yazıda ise devam niteliğinde teorik kısma çok değinmeden pratik olarak nasıl çalıştığnı inceleyeceğiz.
Asp .Net Core SignalR Nasıl Çalışır?
Yukardaki şemada görüldüğü gibi SignalR yapısının merkezinde Hub dediğimiz bir yapı mevcuttur. Hub sayesinde Serve ve client arasındaki haberleşmeyi sağlamaktayız. Bu şeklide Herhangi bir clinet'ın vermiş olduğu bildirim ile diğer clientlara hub aracılığı ile gönderiyor. Tabi bahsettiğimiz Hub yapılanması özünde bir class ( sınıf ) olmaktan başka bir şey değil. SignalR'da server tarafını inşa etmek istediğimizde "Hub" class'ından referans alması gerekir.
Artık ufaktan pratiğe geçmemiz gerekiyor. Tabi, her şeyden önce yukarıdaki Şemayı incelersek, SignalR uygulamasının client ile server arasındaki ilişkiden ibaret olduğunu görürüz ve ilk aşamada server’ın tarafının hazırlanması ve ardından ona uygun bir client hazırlığının yapılması gerektiğini söyleyebiliriz. Bun istinaden ilk olarak server’ın hazrılanmasını ele alacağız, ardından hazırladığımız server’a uygun client'ın nasıl olacağını ele alacağız.
Server ve Hub Class'ı
Eğer çalıştğınız Asp .Net Core sürümü 5.0'ın altındaysa Microsoft.AspNetCore.SignalR paketini indirmeniz gerekir, eğer Asp .Net Core 5.0 veya üzerinde çalışıyorsanız bu paket dahili olara geldiğinden indirmenize gerek yoktur.
Öncelikle SignalRChatExample isimli bir projemiz olsun, Hubs klasörünün içine MessageHub (isimlendirme standarlarına göre sonuna Hub ibaresini ekledik) adlı bir Hub class'ı oluşturalım.
Not: |
Oluşturulan klasör içerisine hub’larımızı oluşturacağız. Bizler Misal olsun diye ilk olarak ‘MessageHub’ adını verdik. Bir class’ın hub olabilmesi için Microsoft.AspNetCore.SignalR kütüphanesindeki ‘Hub’ sınıfından türemesi lazımdır. |
Misalen, Hub'ımızın clint'lara herhangi bir bildirim veya ileti gönderebilmesi için metodu oluşturalım.
public async Task MessageSendingAsync(string message, string userName)
{
await Clients.All.SendAsync("receivedMessage", message, userName)
}
Client property'si Hub base class'ından bizim Hubımıza gelmekte ve bu yapıda bizim clinet'laramızı temsil etmektedir. Client.All komutu iletiyi gönderen dahil olmak üzere tüm clinetlara karışılık geliyor. SendAsync fonksiyonu içinde tanımladığımız receivedMessage değerine karşılık hub'a subsicribe ( abone ) olan client'lar da bir metot bekletiyor ve hub üzerinrden MessageSendingAsync'a herhangi bir tetikleme geldiği vakit anında clinetları ilgili fonksiyon üzerinden bilgilendiriyor.
MessageSendingAsync metodu aktifleştiğinde Clients property'is üzerinden receivedMessage metodu Hub'a bağlı olan tüm clilentlardan iletiyi gönderir ve bütün clinetlara iletimiz gitmiş olacaktır.
Şimdi ise projemizde SignalR'ı konfigure edelim.
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews();
services.AddSignalR();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapDefaultControllerRoute();
endpoints.MapHub<MessageHub>("/messagehub");
});
}
}
//.Net Core 6.0 ile beraber kullanım ( porgram.cs içinde )
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddSignalR();
builder.Services.AddControllersWithViews();
var app = builder.Build();
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapDefaultControllerRoute();
endpoints.MapHub<MessageHub>("/messagehub");
});
app.Run();
ConfigureServices altında services.AddSignalR servisini çağırdık ardından Configure içerisinde app.UseEndpoints altında endpoints.MapHub<MessageHub>(
"/messagehub"
)
şeklinde endpoint'i ayarladık. Burada https.localhost:44894/messagehub şeklinde olacak.
Client Side Library
Artık sırada hazırladığımız server'a uygun bir client hazırlamakta. İlk adım olarak projemize Client Side Library aracılığı ile npm modülünden @microsoft/signalr istemci paketini indirmek olacak ( wwwroot → Add → Client Side Library )
Massage adında bir Controllerimiz ve Chat adında Aciton metodumuz olsun.
public class MessageController : Controller
{
public IActionResult Chat()
{
return View();
}
}
Chat action metodumuza bir View oluşturalım ve client'ımızı hazırlayalım.
<html>
<head>
<script src="~/microsoft/signalr/signalr.min.js"></script>
<script src="~/lib/jquery/dist/jquery.min.js"></script>
<script>
$(document).ready(() => {
//SignalR için JavaScript kodları burada yazılacak...
});
</script>
</head>
<body>
<div class="container">
<div class="row p-1">
<div class="col-1">User</div>
<div class="col-5"><input type="text" id="txtUserName" /></div>
</div>
<div class="row p-1">
<div class="col-1">Message</div>
<div class="col-5"><input type="text" class="w-100" id="txtMassage" /></div>
</div>
<div class="row p-1">
<div class="col-6 text-end">
<button type="button" id="btnSendButton">Gönder</button>
</div>
</div>
<div class="row p-1">
<div class="col-6">
<hr />
</div>
</div>
<div class="row p-1">
<div class="col-6">
<ul id="messagesList"></ul>
</div>
</div>
</div>
</body>
</html>
Yukarıda kullanıcı adını, mesajı ve alabilmak için iki input nesnesi ve mesajı gönderebilmek için ise bir button nesnebi eklemiş olduk.
İlk olarak server tarafında hub'ımızı ayağa kaldıralım ve Hub endpoint'i ile connection'ı ( bağlantıyı ) yapalım.
var connection = new signalR.HubConnectionBuilder()
.withUrl("https://localhost:44331/messagehub")
.build();
şimdi ise start komutu ile bağlantıyı başlatalım.
connection.start();
Bu şekilde projemiz hub ile bağlantı kurabilecek.
Yukarıda hazırladığımız server'a uygun bir şekilde Gönder butonuna tıklandığında input nesneleremizideki verileri okuyalım ve connection.invoke fonksiyonu ile hub'ımızdaki MessageSendingAsync metonun çağırıp message ve userName verilerini alalım.
$("button").click(() => {
let userName = $("#txtUserName").val();
let message = $("#txtMessage").val();
connection.invoke("SendingMessageAsync", message, userName)
.catch(error => console.log("Mesaj gönderilirken hata alınmıştır."));
});
public async Task MessageSendingAsync(string message, string userName)
{
await Clients.All.SendAsync("receivedMessage", message, userName)
}
Yurakıdaki metot bizim server tarafında hazırladğımız hub idi burada metodumuza gelen tüm istekler receivedMessage parametresini dinleyen tüm client'lara gönderilecektir. Buna istinaden bizde client tarafında receviedMessage fonksiyonunu tanımlamamız gerekiyor.
connection.on("receivedMessage", message, userName) => {
$("#messagesList").append(`${userName}: ${message}<br />`);
});
Görüleceği üzere metodumuz tetikleneceği zaman receivedMessage fonksiyonumuza subscribe olan tüm client'lara ilgili değerler gidecektir. kısaca client tarafın kodları bu şekilde olacaktır.
<script>
$(document).ready(() => {
var connection = new signalR.HubConnectionBuilder()
.withUrl("https://localhost:44331/messagehub")
.build();
connection.start();
$("button").click(() => {
let userName = $("#txtUserName").val();
let message = $("#txtMessage").val();
connection.invoke("SendingMessageAsync", message, userName)
.catch(error => console.log("Mesaj gönderilirken hata alınmıştır."));
});
connection.on("receivedMessage", message, userName) => {
$("#messagesList").append(`${userName}: ${message}<br />`);
});
});
</script>
Cors Politikaları
Eğer SignalR projenizi Visual Studio içinde yapıyorsanız bu Cors Politikası ayarlaması yapmanız gerekmez lakin, Visual Stdio dışında herhangi bir editor ile yapıyorsanız bu ayarlamayı yapmamız gerekecektir aksi halde hata alırız, bizde bu ayarlamayı yapacağız.
Kısaca CORS, "Cross-Origin Resource Sharing" ifadesinin kısaltmasıdır ve bir kökende çalışan web uygulamasının, farklı bir kökende yer alan web uygulamalarına erişim izni kontrolünü sağlamak için kullanılan bir mekanizmadır diyebiliriz.
Cors Politikası için aşağıdaki konfigurasyonu Startup.cs içinde yapalım.
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews();
services.AddCors(opt => opt.AddDefaultPolicy(policy =>
policy.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials()
.SetIsOriginAllowed(origin => true)
));
services.AddSignalR();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
//app.UseCors();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapHub<MessageHub>("/messagehub");
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
});
}
projemizi F5 ile çalıştırıp test ettiğimizde sorunsuz bir şekilde çalışacaktır.
Bu yazımızın sonuna geldik, bu şekilde Asp .Net Core SignalR da basit bir sohbet uygulaması yapmış olduk. sonraki yazımızda yine SignalR üzerinden ilereleyeceğiz. bu yazıya ilişkin projeyi github adresi üzerinden indirebilirsiniz. ilgilenenlerin faydalanması ümidiyle.
Yorumlar
Ad: Hasan BOZKUŞ
Başlık: Tema Hakkında
Bu şekilde de iyi, ben sıkıntı görmüyorum.
20.02.2024
Ad: Burak Temelkaya
Başlık: Karanlık temada kod kısmı gözükmüyordu düzeltildi.
Karanlık temada kod kısmı gözükmüyor css'leri düzelttim. Resimlerdeki boşluk olayını da düzelttim. Başka bir öneri vermek istersen yazabilirsin.
18.02.2024
Bir Yorum Bırak