C# İle Websocket Protokolü Kullanarak Canlı Veri Akışı Nasıl Yapılır?

C# İle Websocket Protokolü Kullanarak Canlı Veri Akışı Nasıl Yapılır?
C# İle Websocket Protokolü Kullanarak Canlı Veri Akışı Nasıl Yapılır?

Gereksinimler ve Ön Hazırlık

Projeye başlamadan önce sisteminizde gerekli olan araçların güncel sürümlerinin yüklü olduğundan emin olmalısınız. 2026 standartlarına uygun olarak .NET 9 veya üzeri bir sürüm kullanmanızı öneriyoruz.

  • SDK: .NET 9.0 SDK veya daha yeni bir sürüm.
  • IDE: Visual Studio 2022 (v17.12+) veya VS Code (C# Dev Kit eklentisi ile).
  • Protokol Bilgisi: HTTP üzerinden el sıkışma (handshake) ve ardından TCP tabanlı sürekli bağlantı mantığı.

Yeni bir ASP.NET Core Web API projesi oluşturarak işe başlayabilirsiniz. Terminal üzerinden şu komutu kullanarak temel yapıyı hazırlayın:

dotnet new web -n CanliVeriAkisiProjesi
cd CanliVeriAkisiProjesi

Bu komut, minimalist bir ASP.NET Core uygulaması oluşturur. Websocket desteği için ek bir kütüphaneye ihtiyaç duymadan, .NET'in yerleşik Microsoft.AspNetCore.WebSockets paketini kullanacağız.

Websocket Middleware Yapılandırması

Websocket bağlantılarını kabul edebilmek için uygulamanın HTTP isteklerini dinlerken Websocket protokolünü desteklemesi gerekir. Bu işlem, Program.cs dosyasında middleware (ara yazılım) yapılandırması ile yapılır.

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

app.UseWebSockets();

app.Use(async (context, next) =>
{
    if (context.Request.Path == "/ws")
    {
        if (context.WebSockets.IsWebSocketRequest)
        {
            using var webSocket = await context.WebSockets.AcceptWebSocketAsync();
            await HandleWebSocketConnection(webSocket);
        }
        else
        {
            context.Response.StatusCode = StatusCodes.Status400BadRequest;
        }
    }
    else
    {
        await next();
    }
});

app.Run();

Yukarıdaki kod, /ws rotasına gelen istekleri kontrol eder. Eğer istek bir Websocket isteği ise bağlantıyı kabul eder ve HandleWebSocketConnection metoduna yönlendirir. Bu yapı, uygulamanızın canlı veri akışını başlatması için gereken kapıyı açar.

Sunucu Tarafında Veri İşleme ve Gönderme

Bağlantı kurulduktan sonra, istemciye sürekli veri göndermek için bir döngüye ihtiyacınız vardır. Bu döngü, bağlantı açık kaldığı sürece çalışmalı ve verileri byte dizisi (array) formatında iletmelidir.

private static async Task HandleWebSocketConnection(WebSocket webSocket)
{
    var buffer = new byte[1024 * 4];
    while (webSocket.State == WebSocketState.Open)
    {
        var message = $"Sunucu Zamanı: {DateTime.Now:HH:mm:ss}";
        var bytes = System.Text.Encoding.UTF8.GetBytes(message);
        
        await webSocket.SendAsync(new ArraySegment(bytes), 
            WebSocketMessageType.Text, true, CancellationToken.None);
            
        await Task.Delay(1000); // 1 saniye aralıkla veri gönder
    }
    await webSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, "Bağlantı kapatıldı", CancellationToken.None);
}

Bu metot, her saniye güncel zaman bilgisini istemciye gönderir. ArraySegment kullanımı, verinin ağ üzerinden gönderilmeden önce byte dizisine dönüştürülmesini sağlar. Task.Delay ise sunucuyu yormamak için veri akışını sınırlandırır.

İstemci Tarafında Bağlantı Kurma

Sunucudaki canlı veri akışını test etmek için tarayıcı konsolunu veya basit bir HTML/JavaScript istemcisi kullanabilirsiniz. Aşağıdaki kod, sunucuya bağlanıp gelen veriyi ekrana yazdırır.

const socket = new WebSocket("ws://localhost:5000/ws");

socket.onmessage = function(event) {
    console.log("Sunucudan gelen veri:", event.data);
};

socket.onopen = function() {
    console.log("Bağlantı başarıyla kuruldu.");
};

Bu JavaScript kodu, sunucunun /ws uç noktasına bağlanır. Bağlantı açıldığında ve sunucudan her mesaj geldiğinde konsola bilgi yazdırır. Bu, canlı veri akışının doğrulanması için en hızlı yöntemdir.

Websocket vs HTTP Polling Karşılaştırması

Canlı veri akışı için kullanılan yöntemlerin avantaj ve dezavantajlarını anlamak, doğru mimariyi seçmenize yardımcı olur.

Özellik Websocket HTTP Polling
Bağlantı Sürekli (Persistent) İstek başına (Stateless)
Gecikme Çok Düşük Yüksek
Sunucu Yükü Düşük Yüksek (Sürekli istek)
Çift Yönlü Evet Hayır

Güvenlik ve Performans Optimizasyonları

Kritik Uyarı: Websocket bağlantılarını üretim ortamında (production) kullanırken mutlaka WSS (Secure Websocket) protokolünü tercih edin. Ayrıca, bağlantı isteklerini doğrulamak için kimlik doğrulama (Authentication) mekanizmalarını (JWT gibi) mutlaka uygulayın.

Güvenliği sağlamak için gelen istekleri filtrelemek ve yetkisiz erişimleri engellemek gerekir. Aşağıdaki örnekte, bağlantı sırasında token kontrolü yapılması önerilir:

if (context.Request.Query.TryGetValue("token", out var token))
{
    if (ValidateToken(token)) { /* Bağlantıyı kabul et */ }
    else { context.Response.StatusCode = StatusCodes.Status401Unauthorized; }
}

Performans için ise, aynı anda binlerce bağlantıyı yönetmeniz gerekiyorsa SignalR kütüphanesini kullanmayı düşünmelisiniz. SignalR, Websocket'i otomatik olarak yönetir ve bağlantı koptuğunda yeniden bağlanma (reconnect) gibi özellikleri yerleşik olarak sunar.

Sıkça Sorulan Sorular

Websocket bağlantısı neden sürekli kopuyor?

Bağlantı kopmaları genellikle sunucu tarafındaki zaman aşımı (timeout) sürelerinden veya ağdaki bir "load balancer"ın boşta kalan bağlantıları kapatmasından kaynaklanır. "Keep-alive" mesajları göndererek bağlantıyı canlı tutabilirsiniz.

Aynı anda kaç kullanıcı bağlanabilir?

Bu tamamen sunucunuzun RAM ve CPU kaynaklarına bağlıdır. Her bir Websocket bağlantısı sunucuda az da olsa bir bellek alanı kaplar. Düzgün yapılandırılmış bir sunucuda on binlerce eşzamanlı bağlantı yönetilebilir.

SignalR kullanmalı mıyım?

Eğer çok karmaşık bir canlı sistem (örneğin çok oyunculu oyunlar veya büyük çaplı chat uygulamaları) geliştiriyorsanız, SignalR'ın sunduğu "fallback" (Websocket desteklenmiyorsa Long Polling'e geçme) özellikleri işinizi çok kolaylaştıracaktır.

Veri güvenliğini nasıl sağlarım?

Websocket üzerinden gönderilen veriler açık metin (plain text) olabilir. Bu yüzden mutlaka TLS/SSL sertifikası kullanarak veriyi şifreleyin. Ayrıca, istemciden gelen verileri her zaman sunucu tarafında valide edin (XSS ve Injection saldırılarına karşı).

Websocket ile dosya gönderilebilir mi?

Evet, ancak Websocket metin ve binary (ikili) veri taşıma protokolüdür. Büyük dosyaları parçalara bölerek (chunking) göndermek, bağlantının kesilmesi durumunda verinin bozulmasını önlemek için en iyi yöntemdir.

Websocket Uygulamalarında Hata Ayıklama ve İzleme Stratejileri

Canlı veri akışı sağlayan sistemlerde, bağlantı sorunlarını teşhis etmek ve anlık veri trafiğini izlemek, uygulamanın kararlılığı için kritik öneme sahiptir. Websocket trafiği standart HTTP isteklerinden farklı olarak uzun süreli açık bağlantılar (persistent connections) kullandığı için geleneksel loglama yöntemleri yetersiz kalabilir.

İstemci Tarafında Ağ İzleme

Tarayıcı geliştirici araçları (F12), Websocket trafiğini incelemek için en temel araçtır. Network sekmesi altında WS filtresini seçerek, sunucu ile istemci arasında gidip gelen tüm "frame"leri görebilirsiniz. Burada dikkat etmeniz gerekenler:

  • Status Code 101: Bağlantının başarıyla yükseltildiğini (Switching Protocols) gösterir.
  • Payload: Gönderilen ve alınan verilerin JSON formatında doğruluğunu kontrol edin.
  • Time: Bağlantının ne kadar süredir açık olduğunu ve gecikme sürelerini (latency) analiz edin.

Sunucu Tarafında Loglama ve Diagnostic

ASP.NET Core üzerinde Websocket hatalarını yakalamak için middleware katmanında özel bir hata yakalama bloğu kullanmalısınız. Özellikle WebSocketException hatalarını loglamak, bağlantı kopmalarının temel nedenini (örneğin; istemcinin beklenmedik şekilde bağlantıyı kesmesi veya timeout) anlamanıza yardımcı olur.

public async Task HandleWebSocketConnection(HttpContext context, WebSocket webSocket)
{
    var buffer = new byte[1024 * 4];
    try
    {
        while (webSocket.State == WebSocketState.Open)
        {
            var result = await webSocket.ReceiveAsync(new ArraySegment(buffer), CancellationToken.None);
            if (result.MessageType == WebSocketMessageType.Close) break;
        }
    }
    catch (WebSocketException ex)
    {
        // Hata loglama mekanizması
        Console.WriteLine($"Bağlantı hatası: {ex.WebSocketErrorCode} - {ex.Message}");
    }
    finally
    {
        if (webSocket.State != WebSocketState.Aborted)
            await webSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, "Kapatılıyor", CancellationToken.None);
    }
}

Üretim Ortamında Ölçeklendirme ve Deployment İpuçları

Uygulamanızı yerel ortamdan canlı ortama (production) taşırken, Websocket bağlantılarının sunucu kaynaklarını nasıl tükettiğini göz önünde bulundurmalısınız. Özellikle Load Balancer (Yük Dengeleyici) kullanımı, Websocket trafiği için özel yapılandırmalar gerektirir.

Load Balancer Yapılandırması

Birden fazla sunucu (server farm) kullanıyorsanız, "Sticky Session" (Session Affinity) özelliğinin aktif olması gerekir. Aksi takdirde, istemci bağlantısı sürekli farklı sunuculara yönlendirilir ve bağlantı kopmaları yaşanır. Nginx veya IIS üzerinde şu ayarları kontrol etmelisiniz:

  • Nginx: proxy_set_header Upgrade $http_upgrade; ve proxy_set_header Connection "Upgrade"; yönergelerinin eklendiğinden emin olun.
  • Timeout Ayarları: Load balancer'ın boşta kalan bağlantıları (idle connections) çok erken kapatmadığından emin olmak için timeout süresini artırın.

Bellek Yönetimi

Her bir Websocket bağlantısı sunucuda bir miktar bellek (RAM) tüketir. Binlerce eşzamanlı bağlantı hedefliyorsanız, ArrayPool kullanarak bellek tahsisini optimize edin. Bu, Garbage Collector (GC) üzerindeki yükü azaltarak uygulamanın daha akıcı çalışmasını sağlar.

using System.Buffers;

// Veri alırken bellek havuzunu kullanma
var buffer = ArrayPool.Shared.Rent(4096);
try
{
    var result = await webSocket.ReceiveAsync(new ArraySegment(buffer), CancellationToken.None);
    // İşlemler...
}
finally
{
    ArrayPool.Shared.Return(buffer);
}

Bu optimizasyonlar, özellikle yüksek trafikli finansal veri akışı veya canlı sohbet uygulamaları gibi gerçek zamanlı sistemlerde sunucunun yanıt süresini (response time) milisaniyeler seviyesinde tutmanıza olanak tanır.

Sonuç

C# ve ASP.NET Core kullanarak Websocket protokolü ile canlı veri akışı sağlamak, modern web uygulamaları için oldukça verimli bir yöntemdir. Bu rehberde, temel bağlantı kurma, veri iletimi ve güvenlik önlemleri konularını ele aldık. Bir sonraki adım olarak, SignalR kütüphanesini inceleyerek daha ölçeklenebilir ve hata toleransı yüksek sistemler kurmayı deneyebilirsiniz.

Yasal Sorumluluk Reddi: Bu makalede paylaşılan kod örnekleri eğitim amaçlıdır. Üretim ortamında kullanmadan önce güvenlik açıklarını (SQL Injection, XSS, CSRF) kontrol etmeli ve profesyonel güvenlik testlerinden geçirmelisiniz. Yazılım geliştirme süreçlerinde oluşabilecek veri kayıplarından veya güvenlik ihlallerinden kullanıcı sorumludur.

Bu yazıya tepkinizi paylaşın:
Kerem Demir

Mutfak pratikleri ve ev ekonomisi konularında uzmanlaşmış bir editörüm. Okuyucularıma bütçe dostu ve uygulanabilir yaşam tavsiyeleri sunuyorum.

Yorumlar (0)

Yorum Yaz