.NET SignalR: Gerçek Zamanlı Uygulamalar İçin Köprü (ASP.NET Core Minimal API Örneği)
Günümüzün modern web uygulamaları, sadece statik içerik sunmaktan çok daha fazlasını yapmayı hedefler. Canlı sohbet odaları, gerçek zamanlı bildirimler, canlı spor skorları, oyunlar veya işbirliği araçları gibi interaktif deneyimler, anlık iletişim gereksinimini artırmaktadır. Geleneksel HTTP istek-yanıt modeli bu tür senaryolar için yetersiz kalırken, sunucudan istemciye anlık veri akışı sağlayan çözümlere ihtiyaç duyulur. İşte bu noktada .NET SignalR devreye giriyor!
Bu blog yazısında, SignalR'ın ne olduğunu, temel amacını, sunduğu avantajları ve özellikle .NET 9 ile gelen Minimal API'ler ile birlikte nasıl kullanılabileceğini basit bir örnekle inceleyeceğiz.
.NET SignalR Nedir?
SignalR, Microsoft tarafından geliştirilen ve ASP.NET geliştiricilerinin web uygulamalarına gerçek zamanlı işlevsellik eklemesini sağlayan açık kaynaklı bir kütüphanedir. Sunucu ile istemciler (web tarayıcıları, mobil uygulamalar vb.) arasında iki yönlü (bidirectional) ve kalıcı bağlantıları kolaylaştırır. SignalR, WebSockets, Server-Sent Events (SSE) ve Long Polling gibi farklı taşıma mekanizmalarını otomatik olarak yönetir ve istemci ve sunucu arasındaki en uygun bağlantı yöntemini otomatik olarak seçer.
SignalR'ın Amacı ve Faydaları
SignalR'ın temel amacı, sunucudan istemciye veri “itme” (push) yeteneği sağlayarak gerçek zamanlı web işlevselliğini basitleştirmektir. Geleneksel olarak, istemcilerin yeni veri olup olmadığını sürekli olarak kontrol etmesi (polling) gerekirdi; bu da gereksiz ağ trafiğine ve sunucu yüküne neden oluyordu. SignalR bu sorunu ortadan kaldırır.
SignalR kullanmanın başlıca faydaları:
Gerçek Zamanlı İletişim: Sohbet uygulamaları, canlı skor tabloları, bildirim sistemleri, işbirliği araçları gibi anlık güncellemeler gerektiren uygulamalar geliştirmeyi kolaylaştırır.
Basit API: Karmaşık bağlantı yönetimi, WebSockets veya diğer gerçek zamanlı teknolojilerin düşük seviyeli detaylarıyla uğraşmak zorunda kalmadan, kolay kullanımlı bir API sunar.
Otomatik Taşıma Yönetimi: WebSockets, Server-Sent Events, Long Polling gibi taşıma yöntemlerini otomatik olarak seçer ve geri dönüş (fallback) mekanizmalarını yönetir. Geliştiricinin tarayıcı uyumluluğu veya ağ koşulları hakkında endişelenmesine gerek kalmaz.
İstemci Geniş Desteği: JavaScript, .NET (C#), Java (Android), Swift (iOS) istemci kütüphaneleri sunar, bu da farklı platformlarda gerçek zamanlı uygulamalar geliştirmeyi mümkün kılar.
Yüksek Ölçeklenebilirlik: Birden fazla sunucuya dağıtılabilir ve Azure SignalR Service gibi bulut hizmetleriyle entegre edilerek milyonlarca eşzamanlı bağlantıyı destekleyebilir.
Gruplar ve Kullanıcılar: Bağlantıları gruplara ayırabilir veya belirli kullanıcılara mesaj gönderebilirsiniz, bu da mesajları hedeflenen kitlelere ulaştırmayı kolaylaştırır.
ASP.NET Core Minimal API ile SignalR Kullanım Örneği
.NET 9 ile Minimal API'ler, hafif ve hızlı API'ler oluşturmak için mükemmel bir seçenek sunarken, SignalR ile birleştiğinde güçlü gerçek zamanlı mikroservisler oluşturmak için ideal bir kombinasyon oluşturur.
Aşağıda, Minimal API kullanarak basit bir sohbet uygulamasının arka ucunu SignalR ile nasıl kurabileceğinizi gösteren bir örnek bulunmaktadır:
1. NuGet Paketlerini Yükleme:
Projenize Microsoft.AspNetCore.SignalR
paketini ekleyin:
Install-Package Microsoft.AspNetCore.SignalR
2. Program.cs
Konfigürasyonu (Minimal API):
SignalR'ı Minimal API uygulamanıza entegre etmek için Program.cs
dosyanızı aşağıdaki gibi düzenleyin:
// Program.cs
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.SignalR;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using System.Threading.Tasks;
var builder = WebApplication.CreateBuilder(args);
// SignalR servislerini ekle
builder.Services.AddSignalR();
builder.Services.AddCors(options =>
{
options.AddDefaultPolicy(builder =>
{
builder.WithOrigins("http://localhost:port", "http://127.0.0.1:port") // İstemcinizin adresini buraya ekleyin
.AllowAnyHeader()
.AllowAnyMethod()
.AllowCredentials();
});
});
var app = builder.Build();
// CORS'u etkinleştir
app.UseCors();
// Routing'i etkinleştir
app.UseRouting();
// SignalR Hub'ı haritala
app.MapHub<ChatHub>("/chatHub");
// Minimal API endpoint'leri
app.MapGet("/", () => "SignalR ile Gerçek Zamanlı Uygulama!");
app.MapGet("/send-message", async (string user, string message, IHubContext<ChatHub> hubContext) =>
{
await hubContext.Clients.All.SendAsync("ReceiveMessage", user, message);
return Results.Ok($"Mesaj gönderildi: {user}: {message}");
});
app.Run();
// SignalR Hub sınıfı
public class ChatHub : Hub
{
public async Task SendMessage(string user, string message)
{
// Bağlı tüm istemcilere mesajı gönder
await Clients.All.SendAsync("ReceiveMessage", user, message);
}
}
Kod Açıklaması:
builder.Services.AddSignalR();
: SignalR hizmetlerini DI konteynerine ekler.builder.Services.AddCors(...)
: İstemci tarafında farklı bir origin'den bağlanıyorsanız, CORS ayarlarını yapmanız gerekir.AllowCredentials()
önemli.app.UseCors();
: CORS middleware'ini etkinleştirir.app.MapHub<ChatHub>("/chatHub");
:ChatHub
sınıfını/chatHub
URL'sine haritalar. İstemciler bu URL üzerinden Hub'a bağlanacaktır.ChatHub
sınıfı: SignalR Hub'ı temsil eder. İstemciler bu Hub üzerindeki metotları çağırabilir (örneğinSendMessage
).Clients.All.SendAsync()
metodu ile Hub, tüm bağlı istemcilereReceiveMessage
adlı bir metodu çağırarak veri gönderebilir./send-message
Minimal API endpoint'i: Bu endpoint, harici bir HTTP isteği ile SignalR Hub'a mesaj göndermek için kullanılabilir.IHubContext<ChatHub>
enjekte edilerek Hub dışından da mesaj gönderilebilir.
3. İstemci Tarafı (Basit JavaScript Örneği):
Bir HTML dosyası ve basit bir JavaScript ile bu Hub'a bağlanabilirsiniz.
<!DOCTYPE html>
<html>
<head>
<title>SignalR Minimal API Sohbet</title>
<style>
body { font-family: sans-serif; margin: 20px; }
#messagesList { list-style-type: none; padding: 0; }
#messagesList li { background-color: #f0f0f0; margin-bottom: 5px; padding: 8px; border-radius: 4px; }
#messageInput { width: 300px; padding: 8px; }
#userInput { width: 100px; padding: 8px; }
button { padding: 8px 15px; cursor: pointer; }
</style>
</head>
<body>
<h1>SignalR Sohbet</h1>
<div id="connectionStatus">Bağlantı durumu: Bağlanmadı</div>
<hr />
<div>
Kullanıcı: <input type="text" id="userInput" value="Anonim" />
Mesaj: <input type="text" id="messageInput" />
<button id="sendButton" disabled>Gönder</button>
</div>
<hr />
<ul id="messagesList"></ul>
<!-- SignalR JavaScript istemci kütüphanesini ekle -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/microsoft-signalr/8.0.0/signalr.min.js"></script>
<script>
const connection = new signalR.HubConnectionBuilder()
.withUrl("https://localhost:port/chatHub") // API'nizin doğru adresini ve portunu kullanın
.withAutomaticReconnect()
.build();
const connectionStatus = document.getElementById("connectionStatus");
const sendButton = document.getElementById("sendButton");
const userInput = document.getElementById("userInput");
const messageInput = document.getElementById("messageInput");
const messagesList = document.getElementById("messagesList");
// Mesaj alma olayını dinle
connection.on("ReceiveMessage", (user, message) => {
const li = document.createElement("li");
li.textContent = `${user}: ${message}`;
messagesList.appendChild(li);
});
// Bağlantı durumunu güncelle
connection.onreconnecting(() => {
connectionStatus.textContent = "Bağlantı durumu: Yeniden bağlanılıyor...";
sendButton.disabled = true;
});
connection.onreconnected(() => {
connectionStatus.textContent = "Bağlantı durumu: Bağlandı.";
sendButton.disabled = false;
});
connection.onclose(() => {
connectionStatus.textContent = "Bağlantı durumu: Bağlantı kesildi.";
sendButton.disabled = true;
// Eğer otomatik yeniden bağlanma kapalıysa, burada bağlantıyı tekrar başlatmayı düşünebilirsiniz.
});
// Bağlantıyı başlat
connection.start()
.then(() => {
connectionStatus.textContent = "Bağlantı durumu: Bağlandı.";
sendButton.disabled = false;
console.log("SignalR bağlantısı başarılı.");
})
.catch(err => {
connectionStatus.textContent = `Bağlantı durumu: Hata - ${err}`;
console.error(err);
});
// Gönder düğmesine tıklama olayını dinle
sendButton.addEventListener("click", () => {
const user = userInput.value;
const message = messageInput.value;
if (user && message) {
// Hub'daki SendMessage metodunu çağır
connection.invoke("SendMessage", user, message)
.catch(err => console.error(err));
messageInput.value = ""; // Mesaj kutusunu temizle
}
});
</script>
</body>
</html>
Çalıştırma:
Yukarıdaki C# kodunu bir ASP.NET Core Minimal API projesinde
Program.cs
içine kopyalayın.appsettings.json
dosyasında SSL portunuzu kontrol edin ve JavaScript kodundakihttps://localhost:port/chatHub
kısmını kendi portunuza göre güncelleyin.Uygulamayı çalıştırın (
dotnet run
).HTML dosyasını bir web tarayıcısında açın.
Aynı HTML dosyasını farklı tarayıcı pencerelerinde açarak sohbetin gerçek zamanlı çalıştığını görebilirsiniz.
Sonuç
.NET SignalR, web uygulamalarınıza gerçek zamanlı yetenekler eklemeyi inanılmaz derecede basitleştiren güçlü bir kütüphanedir. Minimal API'lerle birleştiğinde ise, hızlı, hafif ve yüksek performanslı gerçek zamanlı servisler oluşturmak için ideal bir kombinasyon sunar. Canlı sohbetten gerçek zamanlı analiz panolarına kadar birçok senaryoda SignalR, kullanıcı deneyimini zenginleştirmenize ve uygulamanızın interaktifliğini artırmanıza olanak tanır.
Gerçek zamanlı özelliklere ihtiyaç duyan bir proje üzerinde çalışıyorsanız, .NET SignalR ve Minimal API'lerin gücünü keşfetmeye kesinlikle zaman ayırmalısınız!