Gereksinimler ve Ön Hazırlık
Gerçek zamanlı bir uygulama geliştirmek için sisteminizde belirli araçların kurulu olması gerekir. SignalR, .NET 6 ve üzeri sürümlerde yerleşik olarak gelir, bu nedenle en güncel .NET SDK sürümünü kullanmanız önerilir.
- .NET 8.0 veya 9.0 SDK
- Visual Studio 2022 (v17.x) veya VS Code
- Temel düzeyde C# ve ASP.NET Core bilgisi
- Modern bir web tarayıcısı (Chrome, Edge veya Firefox)
Projenizi oluşturmak için terminal ekranında aşağıdaki komutu kullanarak boş bir web uygulaması başlatabilirsiniz:
dotnet new web -n GercekZamanliSohbet
Bu komut, projeniz için gerekli olan temel dosya yapısını oluşturacaktır. Proje klasörüne girerek geliştirme ortamınızı hazırlamaya başlayabilirsiniz.
SignalR Hub Yapısını Anlamak ve Kurulum
SignalR'ın kalbi "Hub" (merkez) sınıfıdır. Hub, istemcilerin sunucuya mesaj göndermesini ve sunucunun da istemcilere mesaj yayınlamasını sağlayan bir köprü görevi görür. Hub sınıfı, Microsoft.AspNetCore.SignalR.Hub sınıfından türetilir.
Öncelikle projenize SignalR servislerini eklemeniz gerekir. Program.cs dosyanızda şu konfigürasyonu yapmalısınız:
using GercekZamanliSohbet.Hubs;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddSignalR(); // SignalR servisini ekle
var app = builder.Build();
app.MapHub("/chatHub"); // Hub yolunu belirle
app.Run();
Bu kod bloğu, uygulamanızın SignalR protokollerini dinlemesini ve /chatHub adresine gelen bağlantıları yönetmesini sağlar.
Sunucu Tarafında ChatHub Sınıfını Oluşturma
Şimdi istemcilerden gelen mesajları karşılayacak ve diğer istemcilere iletecek olan ChatHub sınıfını yazalım. Bu sınıf, mesajları yönetmek için Clients.All metodunu kullanacaktır.
using Microsoft.AspNetCore.SignalR;
namespace GercekZamanliSohbet.Hubs
{
public class ChatHub : Hub
{
public async Task SendMessage(string user, string message)
{
// XSS koruması için gelen veriyi temizlemeyi unutmayın
await Clients.All.SendAsync("ReceiveMessage", user, message);
}
}
}
Buradaki SendMessage metodu, istemciden gelen kullanıcı adı ve mesaj içeriğini alır, ardından bağlı olan tüm istemcilere ReceiveMessage etiketiyle bu veriyi gönderir.
İstemci Tarafında JavaScript ile Bağlantı Kurma
İstemci tarafında SignalR'ın JavaScript kütüphanesini kullanarak sunucuya bağlanacağız. Bu kütüphane, WebSocket, Server-Sent Events veya Long Polling yöntemlerinden en uygun olanını otomatik seçer.
const connection = new signalR.HubConnectionBuilder()
.withUrl("/chatHub")
.build();
connection.on("ReceiveMessage", (user, message) => {
const li = document.createElement("li");
li.textContent = `${user}: ${message}`;
document.getElementById("messagesList").appendChild(li);
});
connection.start().catch(err => console.error(err.toString()));
Bu JavaScript kodu, sunucuya bağlanır ve ReceiveMessage olayını dinleyerek gelen mesajları HTML listesine ekler.
SignalR İletişim Yöntemlerinin Karşılaştırılması
SignalR, bağlantı kopmalarına karşı otomatik olarak yeniden bağlanma yeteneğine sahiptir. Aşağıdaki tablo, gerçek zamanlı iletişim seçeneklerini özetler:
| Yöntem | Avantajı | Dezavantajı |
|---|---|---|
| WebSockets | En hızlı, düşük gecikme | Eski firewall'larda sorun çıkarabilir |
| Server-Sent Events | Tek yönlü akış için ideal | İstemciden sunucuya veri gönderemez |
| Long Polling | En yüksek uyumluluk | Sunucu yükünü artırır |
Güvenlik ve Üretim Ortamı Uyarıları
Kritik Güvenlik Uyarısı: Üretim ortamında SignalR kullanırken mutlaka CORS (Cross-Origin Resource Sharing) politikalarınızı kısıtlayın. İstemciden gelen mesajları doğrudan HTML'e basmadan önce mutlaka sanitize (temizleme) işleminden geçirin; aksi takdirde XSS (Cross-Site Scripting) saldırılarına açık hale gelirsiniz.
Kullanıcı girişlerini doğrulamak için JWT (JSON Web Token) kullanarak Hub bağlantılarını yetkilendirmeyi (Authorize) ihmal etmeyin. Hub sınıfınıza [Authorize] özniteliğini ekleyerek sadece giriş yapmış kullanıcıların mesaj göndermesini sağlayabilirsiniz.
Sıkça Sorulan Sorular
SignalR bağlantım sürekli kopuyor, ne yapmalıyım?
Bağlantı kopmaları genellikle ağ kesintileri veya sunucu tarafındaki "Keep-Alive" ayarlarından kaynaklanır. İstemci tarafında withAutomaticReconnect() metodunu kullanarak otomatik yeniden bağlanma özelliğini aktif edebilirsiniz.
Aynı anda binlerce kullanıcıyı destekleyebilir miyim?
Evet, ancak ölçekleme için "Backplane" (Redis gibi) kullanmanız gerekir. Bu sayede mesajlar, çoklu sunucu ortamlarında tüm istemcilere senkronize bir şekilde iletilir.
Mesajları veritabanına kaydetmeli miyim?
Gerçek zamanlı sohbet uygulamalarında mesaj geçmişi için SignalR yeterli değildir. Mesajları bir veritabanına (SQL Server veya MongoDB) kaydetmeli ve kullanıcı giriş yaptığında geçmişi veritabanından çekmelisiniz.
SignalR yerine neden WebSockets kullanmayayım?
WebSockets saf bir protokoldür; bağlantı yönetimi, hata ayıklama ve fallback (yedekleme) mekanizmalarını kendiniz yazmanız gerekir. SignalR ise tüm bu karmaşık süreçleri sizin yerinize yönetir.
Hub dışında bir sınıftan mesaj gönderebilir miyim?
Evet, IHubContext arayüzünü kullanarak bir Controller veya Service sınıfı içerisinden de istemcilere mesaj gönderebilirsiniz.
SignalR Uygulamalarında İleri Düzey Hata Ayıklama ve İzleme
Gerçek zamanlı uygulamalarda hata ayıklamak, geleneksel HTTP tabanlı uygulamalara göre daha karmaşıktır. İstemci ve sunucu arasındaki bağlantı kopmaları veya mesaj iletim hatalarını tespit etmek için SignalR'ın sunduğu günlükleme (logging) mekanizmalarını doğru yapılandırmanız gerekir.
İstemci Tarafında Hata İzleme
JavaScript istemcisinde bağlantı durumlarını ve hataları yakalamak için onreconnected, onreconnecting ve onclose metodlarını aktif kullanmalısınız. Aşağıdaki örnek, bağlantı koptuğunda uygulamanın nasıl tepki vereceğini yönetmenizi sağlar:
connection.onclose(error => {
console.error("Bağlantı koptu: " + error);
// Burada kullanıcıya "Bağlantı kesildi, tekrar bağlanılıyor..." uyarısı gösterilebilir.
});
connection.onreconnecting(error => {
console.warn("Bağlantı kurulmaya çalışılıyor...");
});
Sunucu Tarafında Loglama
ASP.NET Core içerisinde SignalR hata ayıklaması yapmak için appsettings.json dosyanızda log seviyesini Debug veya Trace olarak ayarlayabilirsiniz. Bu, özellikle "Handshake" aşamasındaki hataları görmenize yardımcı olur:
{
"Logging": {
"LogLevel": {
"Microsoft.AspNetCore.SignalR": "Debug",
"Microsoft.AspNetCore.Http.Connections": "Debug"
}
}
}
SignalR Uygulamalarını Ölçeklendirme: Redis Backplane Kullanımı
Uygulamanız tek bir sunucuda mükemmel çalışsa bile, kullanıcı sayısı arttığında birden fazla sunucuya (Load Balancer arkasında) geçiş yapmanız gerekecektir. Bu durumda, A sunucusuna bağlı bir kullanıcı, B sunucusuna bağlı bir kullanıcıya mesaj gönderemez. Bu sorunu çözmek için bir "Backplane" (arka plan taşıyıcı) kullanmanız şarttır.
Redis ile Dağıtık Yapı Kurulumu
Redis, SignalR mesajlarını tüm sunucular arasında senkronize etmek için en yaygın kullanılan çözümdür. Projenize Microsoft.AspNetCore.SignalR.StackExchangeRedis paketini ekledikten sonra Program.cs içerisinde şu yapılandırmayı yapmalısınız:
builder.Services.AddSignalR().AddStackExchangeRedis("localhost:6379", options => {
options.Configuration.ChannelPrefix = "ChatApp";
});
Bu yapılandırma ile, bir sunucuya gelen mesaj Redis üzerinden diğer tüm sunuculara yayınlanır (pub/sub), böylece hangi sunucuya bağlı olursa olsun tüm istemciler mesajı anlık olarak alır.
Performans İpuçları
- Mesaj Boyutunu Optimize Edin: SignalR üzerinden gönderdiğiniz JSON verilerini mümkün olduğunca küçük tutun. Büyük veri transferleri için HTTP API'lerini kullanıp, SignalR üzerinden sadece "yeni veri var" bildirimi gönderin.
- Binary Format Kullanımı: Eğer çok yoğun veri transferi yapıyorsanız, JSON yerine MessagePack protokolünü tercih ederek bant genişliği kullanımını %30-%50 oranında düşürebilirsiniz.
- Bağlantı Sayısını İzleyin: Sunucunuzdaki eşzamanlı bağlantı sayısını (Concurrent Connections) izlemek için Prometheus veya Grafana gibi araçlarla metriklerinizi dışarı aktarın.
Sonuç
C# ve SignalR kullanarak gerçek zamanlı bir sohbet uygulaması geliştirmek, modern web projeleri için vazgeçilmez bir yetenektir. Bu rehberde; Hub yapısının kurulumu, istemci-sunucu iletişimi, güvenlik önlemleri ve ölçeklenebilirlik üzerine temel adımları tamamladık. Bir sonraki adım olarak, projenize kullanıcı kimlik doğrulaması ekleyebilir ve mesajları bir veritabanında kalıcı hale getirebilirsiniz.
Yasal Sorumluluk Reddi: Bu makaledeki kod örnekleri eğitim amaçlıdır. Uygulamanızı canlıya almadan önce OWASP standartlarına uygun güvenlik testlerini yapmalı ve veri gizliliği politikalarına uygun hareket etmelisiniz.


Yorumlar (0)
Yorum Yaz