Günümüzün dinamik web uygulamaları, kullanıcılarına anında ve güncel bilgi sağlamak zorundadır. Peki, sunucudan istemciye tek yönlü, gerçek zamanlı veri akışını nasıl etkin ve kolay bir şekilde yönetebiliriz? Bu makalede, özellikle ASP.NET Core ortamında Server-Sent Events (SSE) teknolojisini kullanarak kesintisiz sunucu-istemci iletişimini nasıl kuracağımızı adım adım inceleyeceğiz. Eğer WebForms benzeri olay tabanlı bir yaklaşımdan geliyorsanız ve ASP.NET Core dünyasında gerçek zamanlı bildirimler veya canlı veri akışları oluşturmak istiyorsanız, doğru yerdesiniz. SSE, HTTP tabanlı basitliğiyle bu ihtiyacı karşılamak için güçlü bir alternatiftir.
Modern web uygulamaları, statik HTML sayfalarının ötesine geçerek kullanıcılara dinamik ve interaktif deneyimler sunmayı hedefler. Bir borsa takip uygulaması düşünün; hisse senedi fiyatları anlık olarak güncellenmeli, bir spor müsabakasının canlı skorları her saniyede değişmeli veya bir e-ticaret sitesinde sipariş durumu anında bildirilmelidir. Bu tür senaryolar, sunucunun inisiyatifiyle istemciye veri gönderebildiği “gerçek zamanlı” iletişimi gerektirir. Geleneksel HTTP istek-cevap döngüsü, istemcinin sürekli olarak sunucuya “yeni bir şeyler var mı?” diye sorması (polling) esasına dayanır ki bu da hem gecikmelere yol açar hem de sunucu kaynaklarını verimsiz kullanır. Bu noktada, sunucunun aktif olarak istemciye veri “ittiği” (push) mekanizmalar devreye girer.
Gerçek zamanlı iletişim için farklı teknolojiler mevcuttur. Örneğin, Polling, istemcinin belirli aralıklarla sunucuya istek göndermesiyle çalışır. Bu yöntem basit olsa da, yüksek frekanslı güncellemeler için ağ trafiğini artırır ve gecikmelere neden olabilir. Long Polling ise, istemcinin yaptığı bir isteğin sunucu tarafından bir olay gerçekleşene veya belirli bir zaman aşımı süresine ulaşana kadar açık tutulması prensibine dayanır. Bu, Polling’e göre daha az gecikme sunar ancak yine de her olay için yeni bir HTTP bağlantısı kurulmasını gerektirir. WebSockets ise, istemci ve sunucu arasında tam çift yönlü, kalıcı bir bağlantı oluşturarak iki tarafın da dilediği zaman veri göndermesine olanak tanır. Yüksek performanslı ve düşük gecikmeli çift yönlü iletişim için idealdir. Ancak, tam çift yönlülüğe ihtiyacınız yoksa, yani sadece sunucudan istemciye tek yönlü bir akış yeterliyse, WebSockets biraz aşırıya kaçabilir.
İşte tam bu noktada Server-Sent Events (SSE) devreye girer. SSE, adından da anlaşılacağı gibi, sunucudan istemciye tek yönlü bir olay akışı sağlayan basit ama güçlü bir teknolojidir. HTTP üzerine kuruludur ve geleneksel bir HTTP bağlantısı kullanır, ancak bu bağlantı bir kez kurulduktan sonra sunucu tarafından sürekli açık tutularak istemciye “olaylar” göndermek için kullanılır. Bu, özellikle bildirimler, canlı veri akışları, ilerleme çubukları veya sürekli güncellenen gösterge panelleri gibi senaryolar için mükemmel bir çözümdür. Ayrıca, WebSockets’tan farklı olarak, SSE’nin kullanımı daha basittir çünkü tarayıcı tarafında EventSource API’si ile kolayca entegre edilebilir ve tarayıcılar tarafından otomatik yeniden bağlanma desteği sunar. WebForms ortamından gelip ASP.NET Core’a geçen geliştiriciler için, olay tabanlı bu yaklaşım, belirli olaylara tepki verme alışkanlığına oldukça yakındır ve geçiş sürecini kolaylaştırabilir. ASP.NET Core’un esnek mimarisi sayesinde, SSE endpoint’leri oluşturmak oldukça kolaydır ve bu sayede uygulamanız gerçek zamanlı yeteneklere hızlıca kavuşabilir.
ASP.NET Core’da Server-Sent Events (SSE) Nasıl Çalışır?
Server-Sent Events (SSE), web uygulamalarında sunucudan istemciye tek yönlü veri akışını sağlamak için kullanılan basit ve etkili bir teknolojidir. Temel olarak, standart bir HTTP bağlantısı üzerinden sürekli bir veri akışı oluşturur. Bu akış, istemci tarafından başlatılan tek bir HTTP isteği ile kurulur, ancak bu istek geleneksel isteklerin aksine bir kez cevaplandıktan sonra kapanmaz; sunucu tarafından açık tutularak zaman içinde birden fazla veri paketi göndermek için kullanılır. Bu sayede, sunucu herhangi bir zamanda istemciye veri “push” edebilir, yani iletebilir.
SSE’nin temel çalışma prensibi oldukça basittir. İstemci (genellikle bir web tarayıcısı), JavaScript’in EventSource API’sini kullanarak sunucuya özel bir HTTP isteği gönderir. Bu istek, sunucuya bir SSE akışı başlatmak istediğini bildirir. Sunucu, bu isteği aldığında, cevabın Content-Type başlığını text/event-stream olarak ayarlar. Bu özel Content-Type, tarayıcıya gelen verilerin bir SSE akışı olduğunu ve bunları birer olay olarak işlemesi gerektiğini söyler. Ardından, sunucu veri göndermek istediğinde, belirli bir formatta (data: mesajınız\n\n gibi) veriyi HTTP yanıt akışına yazar ve bu veriler istemciye anında ulaşır.
Bir SSE akışının en önemli özelliklerinden biri, istemci tarafındaki EventSource objesinin otomatik yeniden bağlanma (reconnection) yeteneğidir. Eğer ağ bağlantısı kesilir veya sunucu tarafında bir hata oluşursa, EventSource objesi belirli bir süre sonra otomatik olarak bağlantıyı tekrar kurmaya çalışır. Bu özellik, gerçek zamanlı uygulamalarda bağlantı kesintilerine karşı dayanıklılık sağlar ve geliştiricinin manuel olarak yeniden bağlantı mantığı yazma yükünü azaltır. Ayrıca, sunucu, her olayın başına bir id: alanı ekleyerek olayları numaralandırabilir. İstemci yeniden bağlandığında, en son aldığı olayın ID’sini sunucuya iletebilir (Last-Event-ID başlığı ile), böylece sunucu kesintiden sonra eksik kalan olayları göndermeye devam edebilir. Bu da veri bütünlüğünü sağlamak için önemli bir özelliktir.
ASP.NET Core’da bir SSE endpoint’i oluşturmak için genellikle bir controller metodu veya Minimal API endpoint’i kullanılır. Bu endpoint, isteği yakalar, Response.ContentType‘ı text/event-stream olarak ayarlar ve ardından bir döngü içinde Response.Body.WriteAsync() metodu ile verileri istemciye gönderir. Her veri gönderiminden sonra Response.Body.FlushAsync() çağrılması önemlidir, çünkü bu, arabellekteki verilerin hemen istemciye iletilmesini sağlar. Bu basitlik, ASP.NET Core’un middleware ve esnek HTTP işleme yetenekleri sayesinde kolayca uygulanabilir. Geliştiricilerin WebForms’ta olduğu gibi karmaşık olay döngüleri veya sayfa yaşam döngüsü yönetimi yerine, doğrudan HTTP akışı üzerinde çalışmasına olanak tanır. SSE’nin bu yapısı, tek yönlü veri akışına ihtiyaç duyan birçok senaryo için düşük maliyetli ve yüksek verimli bir çözüm sunar.
Response.Body.FlushAsync() metodunu her veri gönderiminden sonra çağırmayı unutmayın. Aksi takdirde, veriler sunucu arabelleğinde kalabilir ve istemciye ulaşmada gecikmeler yaşanabilir.
Adım Adım ASP.NET Core Uygulamasında SSE Entegrasyonu
ASP.NET Core uygulamanızda Server-Sent Events (SSE) kullanmak, hem backend hem de frontend tarafında birkaç basit adımı izlemeyi gerektirir. Bu bölümde, sıfırdan bir ASP.NET Core projesi oluşturarak, sunucuda bir SSE endpoint’i nasıl tanımlayacağımızı ve istemci tarafında bu akışı nasıl tüketeceğimizi adım adım inceleyeceğiz. Bu rehber, .NET 7 veya .NET 8 kullanan modern bir ASP.NET Core projesi için geçerlidir.
Backend Hazırlığı: Bir SSE Endpoint’i Oluşturmak
Öncelikle, ASP.NET Core projemizi kurarak başlayalım. Eğer henüz bir projeniz yoksa, komut satırından aşağıdaki komutla yeni bir Web API projesi oluşturabilirsiniz:
dotnet new webapi -n SseDemoApp
cd SseDemoApp
Projemizi oluşturduktan sonra, SSE akışını sağlayacak bir controller veya Minimal API endpoint'i tanımlamamız gerekiyor. Minimal API'ler, daha az kodla daha hızlı endpoint'ler oluşturmak için mükemmeldir. Program.cs dosyanızı açın ve aşağıdaki kod bloğunu ekleyin:
// Diğer using ifadeleri...
using System.Threading.Channels;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
// SSE endpoint'imizi tanımlayalım
app.MapGet("/sse", async context =>
{
context.Response.ContentType = "text/event-stream";
context.Response.Headers.Add("Cache-Control", "no-cache");
context.Response.Headers.Add("Connection", "keep-alive");
var lastEventId = context.Request.Headers["Last-Event-ID"].FirstOrDefault();
Console.WriteLine($"İstemci bağlandı. Son Olay ID: {lastEventId}");
for (int i = 0; i < 100; i++) // 100 mesaj göndereceğiz
{
if (context.RequestAborted.IsCancellationRequested)
{
Console.WriteLine("İstemci bağlantısı kesildi.");
break;
}
var message = $"data: Bu {i}. mesajdır. Sunucu saati: {DateTime.Now:HH:mm:ss}\n";
var id = $"id: {i}\n"; // Otomatik yeniden bağlanma için olay ID'si
await context.Response.WriteAsync(id);
await context.Response.WriteAsync(message);
await context.Response.WriteAsync("\n"); // Her olay sonunda iki yeni satır karakteri olmalı
await context.Response.Body.FlushAsync(); // Veriyi anında istemciye gönder
await Task.Delay(TimeSpan.FromSeconds(2)); // Her 2 saniyede bir mesaj gönder
}
Console.WriteLine("SSE akışı tamamlandı.");
});
app.Run();
Yukarıdaki kod bloğunda, /sse adresine yapılan GET isteklerini karşılayan bir Minimal API endpoint'i oluşturduk. İçerideki döngü, her iki saniyede bir istemciye yeni bir mesaj gönderir. context.Response.ContentType = "text/event-stream" satırı, tarayıcıya bu akışın bir SSE akışı olduğunu bildirir. Cache-Control ve Connection başlıkları, bağlantının açık kalmasını ve önbelleğe alınmamasını sağlar. id: {i}\n ve data: ...\n formatı SSE standartlarına uygun mesaj formatıdır ve her mesajdan sonra iki yeni satır karakteri (\n\n veya tek bir \n eğer zaten data: sonunda varsa) olması gerektiğini unutmayın. FlushAsync() çağrısı, verilerin hemen istemciye ulaşmasını sağlar. Ayrıca, context.RequestAborted.IsCancellationRequested ile istemci bağlantısının kopup kopmadığını kontrol ederek gereksiz kaynak kullanımını önlüyoruz.
Frontend (İstemci) Tarafında SSE Tüketimi
Şimdi de istemci tarafında bu SSE akışını nasıl tüketeceğimizi görelim. Basit bir HTML dosyası ve JavaScript kullanarak sunucudan gelen mesajları dinleyeceğiz. Projenizin ana dizininde (veya wwwroot klasöründe) index.html adında bir dosya oluşturun ve aşağıdaki içeriği ekleyin:
SSE İstemcisi
Sunucu-İstemci SSE İletişimi
Sunucu bağlantısı bekleniyor...
Bu HTML dosyasında, EventSource API'sini kullanarak /sse endpoint'ine bağlanıyoruz. eventSource.onopen, eventSource.onmessage ve eventSource.onerror olayları ile bağlantı durumu ve gelen mesajları ele alıyoruz. Gelen her mesaj messagesDiv alanına eklenir. event.lastEventId özelliği, sunucudan gelen son olayın ID'sini içerir ve otomatik yeniden bağlanma senaryolarında sunucunun hangi noktadan devam etmesi gerektiğini belirtmek için kullanılır. Kodu çalıştırabilmek için, Program.cs dosyasındaki app.UseStaticFiles(); satırının uncommented (yorum satırı dışına alınmış) olduğundan ve index.html dosyanızın wwwroot klasöründe bulunduğundan emin olun. Ayrıca, https://localhost:7001 kısmını kendi uygulamanızın çalıştığı port numarasını ayarlamayı unutmayın (genellikle konsol çıktısında görünür).
Gerçek Dünya Senaryolarında SSE Kullanımı: Vaka Analizleri
Server-Sent Events (SSE), tek yönlü gerçek zamanlı iletişim ihtiyacı olan birçok senaryoda etkili bir çözüm sunar. Basitliği ve HTTP üzerine inşa edilmiş olması, onu belirli kullanım durumları için WebSockets'tan daha cazip hale getirebilir. İşte gerçek dünyadan birkaç örnekle SSE'nin nasıl kullanılabileceği:
1. Uzun Süren İşlemlerin Durum Takibi ve İlerleme Çubukları
Bir web uygulamasında büyük bir dosya yükleme, karmaşık bir veri işleme veya rapor oluşturma gibi uzun sürebilen işlemlerle karşılaşmak yaygındır. Kullanıcının bu işlemin bitmesini beklerken sayfanın takılı kalması veya durumunu bilememesi kötü bir kullanıcı deneyimi yaratır. SSE, bu tür senaryolarda kullanıcılara işlemin mevcut durumu veya ilerlemesi hakkında anlık güncellemeler sunmak için idealdir. Örneğin, bir dosya yüklenirken sunucu, yüklenen bayt miktarını veya tamamlanma yüzdesini belirli aralıklarla SSE akışı üzerinden istemciye gönderebilir. İstemci tarafındaki JavaScript kodu, bu veriyi alarak bir ilerleme çubuğunu güncelleyebilir veya durum mesajlarını gösterebilir. Bu, kullanıcının bekleme süresini daha bilgilendirici ve katlanılabilir hale getirir.
// ASP.NET Core Backend (Örnek)
app.MapGet("/progress-updates", async context =>
{
context.Response.ContentType = "text/event-stream";
context.Response.Headers.Add("Cache-Control", "no-cache");
context.Response.Headers.Add("Connection", "keep-alive");
for (int i = 0; i <= 100; i += 10)
{
if (context.RequestAborted.IsCancellationRequested) break;
var message = $"data: {{ \"percentage\": {i}, \"status\": \"İşleniyor...\" }}\n\n";
await context.Response.WriteAsync(message);
await context.Response.Body.FlushAsync();
await Task.Delay(TimeSpan.FromSeconds(1));
}
await context.Response.WriteAsync("data: {\"percentage\": 100, \"status\": \"Tamamlandı!\"}\n\n");
await context.Response.Body.FlushAsync();
});
0%
2. Canlı Veri Akışları ve Gösterge Panelleri (Dashboards)
Finansal uygulamalar, IoT cihazlarından gelen sensör verileri, ağ izleme sistemleri veya sosyal medya akışları gibi birçok alanda, verilerin anlık olarak güncellenmesi ve kullanıcılara sunulması gerekir. SSE, bu tür canlı veri akışlarını oluşturmak için oldukça uygundur. Örneğin, bir IoT platformunda, sensörlerden gelen sıcaklık veya nem verileri sunucuya ulaştığında, bu veriler anında ilgili gösterge panellerine sahip istemcilere SSE üzerinden gönderilebilir. İstemciler bu verileri alarak grafiklerini veya tablolarını dinamik olarak güncelleyebilirler. Bu sayede kullanıcılar, sürekli yenileme yapmalarına gerek kalmadan en güncel bilgilere erişebilirler.
Mobil uyumluluk açısından, bu tür gösterge panellerinin responsive bir tasarıma sahip olması önemlidir. CSS media query'leri kullanarak farklı ekran boyutlarına uygun düzenler oluşturabiliriz:
/* Örnek Mobil Uyumlu CSS */
@media (max-width: 768px) {
.dashboard-widget {
width: 100%; /* Küçük ekranlarda widget'lar tam genişlikte olsun */
float: none;
margin-bottom: 15px;
}
}
3. Anlık Bildirimler ve Haber Akışları
Birçok uygulama, kullanıcılara yeni e-postalar, sosyal medya bildirimleri, yeni haber makaleleri veya mesajlar hakkında anında bilgi vermek ister. SSE, bu tür anlık bildirim sistemleri için basit ve güvenilir bir çözümdür. Sunucu, bir olay (örneğin, yeni bir mesaj gelmesi) gerçekleştiğinde, ilgili kullanıcıların tarayıcılarına bir SSE mesajı gönderebilir. Tarayıcı, bu mesajı alarak bildirim çubuğunu güncelleyebilir, bir popup gösterebilir veya bir ses çalabilir. Bu, kullanıcıların uygulamayla sürekli etkileşimde kalmasına yardımcı olur ve önemli güncellemeleri kaçırmalarını engeller.
Özetle, SSE, sunucudan istemciye tek yönlü, olay tabanlı iletişimde basitlik, verimlilik ve otomatik yeniden bağlanma yeteneği arayan projeler için mükemmel bir seçimdir. Yukarıdaki vaka analizleri, bu teknolojinin geniş bir kullanım yelpazesine sahip olduğunu göstermektedir ve ASP.NET Core ile entegrasyonu oldukça kolaydır.
İleri Düzey SSE Teknikleri ve Performans İpuçları
Server-Sent Events (SSE), basit bir teknoloji olsa da, daha karmaşık senaryolarda ve yüksek performans gerektiren uygulamalarda bazı ileri düzey teknikler ve optimizasyon ipuçları göz önünde bulundurulmalıdır. Bu bölümde, SSE uygulamalarınızı daha sağlam, ölçeklenebilir ve verimli hale getirecek yöntemleri keşfedeceğiz.
1. Mesaj Formatını Zenginleştirmek: JSON Kullanımı
SSE standardı, data: anahtar kelimesinden sonra herhangi bir metin verisinin gönderilmesine izin verir. Ancak, daha yapısal ve karmaşık veriler göndermek istediğinizde, JSON formatını kullanmak en iyi yaklaşımdır. Bu, istemci tarafında verileri kolayca ayrıştırmanızı ve kullanmanızı sağlar.
// ASP.NET Core Backend
app.MapGet("/json-events", async context =>
{
context.Response.ContentType = "text/event-stream";
// ... diğer başlıklar ...
var eventData = new {
Timestamp = DateTime.Now,
Message = "Yeni bir bildiriminiz var!",
Type = "notification",
UserId = 123
};
var jsonMessage = System.Text.Json.JsonSerializer.Serialize(eventData);
await context.Response.WriteAsync($"data: {jsonMessage}\n\n");
await context.Response.Body.FlushAsync();
});
// Frontend JavaScript
eventSource.onmessage = function(event) {
const data = JSON.parse(event.data);
console.log("Gelen Veri:", data);
if (data.Type === "notification") {
alert(data.Message);
}
};
2. Hata Yönetimi ve Otomatik Yeniden Bağlanma Stratejileri
EventSource API'si, otomatik yeniden bağlanma özelliğini yerleşik olarak sunsa da, sunucu tarafında da bu durumu yönetmek önemlidir. İstemci bağlantısının kesildiğini (örneğin tarayıcı kapatıldığında) sunucunun anlaması ve gereksiz kaynakları serbest bırakması gerekir. Yukarıdaki örneklerde kullanılan context.RequestAborted.IsCancellationRequested kontrolü bunun için kritiktir. Ayrıca, sunucudan istemciye gönderilen olayların id: alanına sahip olması, istemcinin bağlantı kesintisi sonrası hangi olaydan devam etmesi gerektiğini belirtmesi açısından önemlidir (Last-Event-ID başlığı ile).
İstemci tarafında onerror olayını daha detaylı ele alarak, bağlantı sorunlarının nedenini loglayabilir ve kullanıcıya bilgilendirici mesajlar gösterebilirsiniz. Yeniden bağlanma süresini kontrol etmek için sunucudan retry: alanı gönderebilirsiniz (örneğin, retry: 5000\n 5 saniye sonra yeniden deneme yapar).
3. Ölçeklenebilirlik ve Dağıtık Sistemlerde SSE
Tek bir sunucu üzerinde SSE uygulaması çalıştırmak basittir, ancak uygulamanız ölçeklendikçe, birden fazla sunucuya yayılması gerekebilir. Bu durumda, SSE bağlantılarının hangi sunucuda olduğunu takip etmek ve belirli bir istemciye mesaj göndermek zorlaşır. İşte bu noktada mesaj kuyrukları (örneğin RabbitMQ, Kafka) veya dağıtılmış önbellek sistemleri (Redis Pub/Sub) gibi araçlar devreye girer. Sunucular, olayları bu merkezi sistemlere gönderir ve SSE bağlantılarını yöneten sunucular da bu olayları dinleyerek ilgili istemcilere iletir. Bu yaklaşım, SSE bağlantılarının birden fazla sunucu arasında dağıtılmasına olanak tanır ve uygulamanızın yatay ölçeklenmesini sağlar.
4. Güvenlik ve Kimlik Doğrulama/Yetkilendirme
SSE bağlantıları da diğer HTTP bağlantıları gibi güvenli olmalıdır. HTTPS kullanmak (SSL/TLS) iletişim trafiğini şifreleyerek man-in-the-middle saldırılarını önler. Ayrıca, bir SSE akışına bağlanmak için kimlik doğrulama ve yetkilendirme mekanizmaları kullanmak esastır. Bu, genellikle bağlantı isteği sırasında JWT (JSON Web Token) veya çerez tabanlı kimlik doğrulama ile gerçekleştirilebilir. İstemci, EventSource objesini oluştururken istek başlıklarına kimlik doğrulama token'ını ekleyemez (EventSource API'sinin doğrudan başlık ekleme desteği yoktur). Bu nedenle, token genellikle URL parametresi olarak gönderilir veya önceden bir çerez ile kimlik doğrulama yapılır.
// Eğer token URL'den gönderiliyorsa (daha az güvenli olabilir, dikkatli kullanılmalı)
const token = "YOUR_AUTH_TOKEN"; // Güvenli bir şekilde alınmalı
const eventSource = new EventSource(/sse?token=${token});
EventSource API'sinin doğrudan özel HTTP başlıkları eklemeye izin vermediğini unutmayın. Çerez tabanlı kimlik doğrulama veya JWT'yi URL parametresi olarak gönderme (ancak XSS saldırılarına karşı dikkatli olunmalıdır) yaygın çözümlerdir.
5. SSE vs. SignalR: Ne Zaman Hangisi?
ASP.NET Core ekosisteminde gerçek zamanlı iletişim denince akla ilk gelen teknolojilerden biri de SignalR'dır. Peki, SSE varken neden SignalR kullanmalıyız veya tam tersi? İşte kısa bir karşılaştırma:
- SSE: Tek yönlü (sunucudan istemciye) iletişim için tasarlanmıştır. Basitliği, HTTP üzerine kurulu olması ve yerleşik yeniden bağlanma desteği avantajlarıdır. Tarayıcı desteği yaygındır (IE hariç). Eğer uygulamanız sadece sunucudan bildirimler, akışlar veya güncellemeler alacaksa, SSE mükemmel ve hafif bir çözümdür.
- SignalR: Tam çift yönlü (sunucu-istemci ve istemci-sunucu) iletişim sağlar. WebSockets'ı destekler, ancak tarayıcı veya ağ koşulları uygun olmadığında otomatik olarak uzun polling gibi diğer taşıma yöntemlerine geri döner. Grup yönetimi, bağlantı yönetimi, kimlik doğrulama gibi zengin özellik setine sahiptir. Anlık sohbet uygulamaları, çok kullanıcılı oyunlar veya karmaşık çift yönlü etkileşim gerektiren senaryolar için idealdir.
Özetle, basit tek yönlü bildirimler ve veri akışları için SSE yeterli ve daha az karmaşıktır. Ancak, istemciden sunucuya da gerçek zamanlı veri göndermeniz gerekiyorsa veya zengin bir bağlantı ve grup yönetimi özelliğine ihtiyacınız varsa, SignalR daha güçlü ve kapsamlı bir çözümdür.
Sonuç ve Sıkça Sorulan Sorular
Bu makalede, ASP.NET Core ortamında Server-Sent Events (SSE) teknolojisini kullanarak gerçek zamanlı sunucu-istemci iletişimini nasıl kuracağımızı detaylıca inceledik. SSE'nin, özellikle tek yönlü veri akışı, anlık bildirimler, canlı güncellemeler ve ilerleme takibi gibi senaryolar için ne kadar basit ve etkili bir çözüm olduğunu gördük. ASP.NET Core'un esnek yapısı sayesinde, sadece birkaç satır kod ile bir SSE endpoint'i oluşturmak ve istemci tarafında EventSource API'si ile bu akışı tüketmek oldukça kolaydır. WebForms'tan ASP.NET Core'a geçiş yapan geliştiriciler için, SSE'nin olay tabanlı yaklaşımı, gerçek zamanlı gereksinimleri modern bir yaklaşımla karşılamak için tanıdık ve verimli bir yol sunar. Güvenlik, ölçeklenebilirlik ve performans gibi ileri düzey konulara da değinerek, daha sağlam ve gerçek dünya uygulamaları için ipuçları verdik. Umarız bu rehber, uygulamalarınıza gerçek zamanlı yetenekler kazandırmanıza yardımcı olur.
Sıkça Sorulan Sorular (SSS)
1. SSE her tarayıcıda çalışır mı?
Evet, modern tarayıcıların büyük çoğunluğu (Chrome, Firefox, Safari, Edge, Opera) Server-Sent Events'ı destekler. Ancak, Internet Explorer ve eski Edge (EdgeHTML) sürümleri SSE desteğine sahip değildir. Bu nedenle, geniş tarayıcı uyumluluğu gerekiyorsa ve IE gibi eski tarayıcıları desteklemeniz şartsa, alternatif çözümleri (örn. long polling veya bir polyfill) değerlendirmeniz gerekebilir.
2. SSE ile WebSockets arasındaki temel fark nedir?
En temel fark, iletişim yönüdür. SSE, sunucudan istemciye tek yönlü (uni-directional) bir iletişim kanalını HTTP üzerinden kurar ve olay tabanlı veri akışı sağlar. WebSockets ise, istemci ve sunucu arasında tam çift yönlü (bi-directional) ve kalıcı bir bağlantı kurar. Eğer sadece sunucudan bildirimlere ihtiyacınız varsa SSE daha basit ve hafif bir çözümdür. İstemciden sunucuya da anlık veri göndermeniz gerekiyorsa WebSockets daha uygun bir seçenektir.
3. SSE güvenlik açısından nasıl ele alınır?
SSE bağlantıları da standart HTTP bağlantıları gibi güvenli olmalıdır. Mutlaka HTTPS (SSL/TLS) kullanarak veri trafiğini şifrelemelisiniz. Kimlik doğrulama ve yetkilendirme için ise, doğrudan EventSource API'si özel başlık göndermeye izin vermediği için, genellikle bağlantı isteği öncesinde çerez tabanlı kimlik doğrulama yapılır veya JWT (JSON Web Token) URL parametresi olarak gönderilir. Ancak URL parametresi kullanımı, token'ın loglarda görünmesi gibi güvenlik riskleri taşıyabileceğinden dikkatli olunmalıdır.
4. ASP.NET Core'da SSE için ek kütüphaneler gerekli mi?
Hayır, ASP.NET Core'da SSE uygulamak için herhangi bir özel üçüncü taraf kütüphaneye ihtiyacınız yoktur. Framework'ün kendi HTTP yanıt akışı (Response.Body.WriteAsync, FlushAsync) ve context.RequestAborted.IsCancellationRequested gibi yerleşik özelliklerini kullanarak bir SSE endpoint'i kolayca oluşturabilirsiniz. İstemci tarafında da modern tarayıcıların yerleşik EventSource API'si yeterlidir.
5. SSE'nin performans üzerindeki etkisi nedir?
SSE, HTTP/1.1 üzerinde çalıştığı için her bağlantı kendi TCP bağlantısını kullanır ve sunucu kaynakları üzerinde bir miktar yük oluşturur. Ancak, WebSockets'a kıyasla daha az protokol yükü taşır. Özellikle çok sayıda bağlantı veya yüksek mesaj frekansı beklenen durumlarda, HTTP/2'nin çoklama (multiplexing) özelliği sayesinde tek bir TCP bağlantısı üzerinden birden fazla SSE akışı yönetilebilir, bu da performansı artırabilir. Genellikle, sunucudan istemciye yoğun tek yönlü veri akışları için oldukça performanslı ve verimli bir çözümdür.
