Loading...

.NET SignalR: Gerçek Zamanlı Uygulamalar İçin Köprü

Bu blog yazısı, modern web uygulamalarına gerçek zamanlı işlevsellik katmak için tasarlanmış güçlü bir kütüphane olan .NET SignalR'ı tanıtıyor. SignalR, sunucu ve istemciler arasında kalıcı, iki yönlü bağlantıları basitleştirerek canlı sohbet, bildirim ve oyun gibi etkileşimli deneyimler sağlıyor. Yazı, Minimal API'lerle entegrasyonu ve temel kullanım örneğini sunarak, geliştiricilere hızlı ve hafif gerçek zamanlı servisler oluşturma olanağı tanıdığını vurguluyor.

.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ğin SendMessage). Clients.All.SendAsync() metodu ile Hub, tüm bağlı istemcilere ReceiveMessage 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:

  1. Yukarıdaki C# kodunu bir ASP.NET Core Minimal API projesinde Program.cs içine kopyalayın.

  2. appsettings.json dosyasında SSL portunuzu kontrol edin ve JavaScript kodundaki https://localhost:port/chatHub kısmını kendi portunuza göre güncelleyin.

  3. Uygulamayı çalıştırın (dotnet run).

  4. HTML dosyasını bir web tarayıcısında açın.

  5. 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!