Java İle Websocket Protokolü Kullanarak Gerçek Zamanlı Sohbet Nasıl Yapılır?

Java İle Websocket Protokolü Kullanarak Gerçek Zamanlı Sohbet Nasıl Yapılır?
Java İle Websocket Protokolü Kullanarak Gerçek Zamanlı Sohbet Nasıl Yapılır?

Gereksinimler ve Ön Hazırlık

Projeye başlamadan önce geliştirme ortamınızın güncel olduğundan emin olmalısınız. 2026 standartlarına uygun olarak Java 21 veya daha yeni bir sürüm kullanmanız önerilir. İhtiyacınız olan temel araçlar şunlardır:

  • JDK 21+: Modern dil özellikleri ve performans iyileştirmeleri için.
  • Spring Boot 3.4+: Websocket desteği için gerekli kütüphaneleri içeren framework.
  • Maven veya Gradle: Bağımlılık yönetimi için.
  • Modern Tarayıcı: İstemci tarafındaki Websocket API testleri için.

Projenizin pom.xml dosyasına gerekli olan spring-boot-starter-websocket bağımlılığını ekleyerek işe başlayın. Bu kütüphane, Websocket protokolünü yönetmek için gereken tüm altyapıyı sağlar.


    org.springframework.boot
    spring-boot-starter-websocket

Websocket Konfigürasyonunun Adım Adım Yapılandırılması

Websocket bağlantılarını kabul etmek ve mesaj trafiğini yönetmek için bir konfigürasyon sınıfı oluşturmanız gerekir. Bu sınıf, mesajların hangi uç noktalar (endpoints) üzerinden iletileceğini belirler.

Aşağıdaki kod örneği, /ws-sohbet uç noktasını tanımlar ve mesajlaşma için STOMP (Simple Text Oriented Messaging Protocol) protokolünü etkinleştirir. STOMP, mesajların belirli kanallar (topic) üzerinden iletilmesini kolaylaştıran bir protokoldür.

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {

    @Override
    public void configureMessageBroker(MessageBrokerRegistry config) {
        config.enableSimpleBroker("/topic");
        config.setApplicationDestinationPrefixes("/app");
    }

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        registry.addEndpoint("/ws-sohbet").withSockJS();
    }
}

Burada /app ön eki, istemciden gelen mesajların işlenmek üzere controller sınıflarına yönlendirileceği adresi temsil ederken, /topic ise sunucunun istemcilere yayın yapacağı kanalları ifade eder.

Mesaj Modeli ve Controller Yapısı

Gerçek zamanlı sohbet uygulamasında, istemci ile sunucu arasında taşınacak veriyi tanımlayan bir POJO (Plain Old Java Object) sınıfına ihtiyacınız vardır. Bu sınıf, gönderen kişiyi ve mesaj içeriğini tutar.

public class SohbetMesaji {
    private String icerik;
    private String gonderen;

    // Getter ve Setter metotları
}

Ardından, gelen mesajları alıp ilgili kanallara dağıtacak olan MessageMapping anotasyonlu bir controller sınıfı oluşturmalısınız. Bu yapı, mesajın işlenip tüm abonelere (subscribers) iletilmesini sağlar.

@Controller
public class SohbetController {

    @MessageMapping("/sohbet.gonder")
    @SendTo("/topic/mesajlar")
    public SohbetMesaji mesajGonder(SohbetMesaji mesaj) {
        return mesaj;
    }
}

İstemci Tarafında Bağlantı Kurma

Sunucu tarafı hazır olduktan sonra, tarayıcı üzerinden bu bağlantıyı kullanacak bir JavaScript istemcisi yazmalısınız. sockjs-client ve stompjs kütüphanelerini kullanarak bağlantıyı başlatabilir ve mesaj dinlemeye başlayabilirsiniz.

var socket = new SockJS('/ws-sohbet');
var stompClient = Stomp.over(socket);

stompClient.connect({}, function (frame) {
    stompClient.subscribe('/topic/mesajlar', function (mesaj) {
        console.log("Yeni mesaj: " + JSON.parse(mesaj.body).icerik);
    });
});

Bu kod bloğu, sunucuya bağlanır ve /topic/mesajlar kanalına abone olur. Sunucudan bu kanala bir veri geldiğinde, konsola yazdırılmasını sağlar.

Websocket İletişim Yöntemleri Karşılaştırması

Sohbet uygulamaları geliştirirken kullanılan farklı yöntemlerin avantaj ve dezavantajlarını anlamak, projenin ölçeklenebilirliği için önemlidir.

Yöntem Avantaj Dezavantaj
Websocket Düşük gecikme, çift yönlü Bağlantı yönetimi karmaşıktır
Long Polling Tüm tarayıcılarda çalışır Yüksek sunucu yükü
Server-Sent Events Tek yönlü, basit Sadece sunucudan istemciye

Güvenlik ve Performans Uyarıları

Kritik Uyarı: Websocket bağlantılarını mutlaka WSS (Websocket Secure) üzerinden, yani SSL/TLS şifrelemesi ile kullanın. Ayrıca, gelen mesajlarda XSS (Cross-Site Scripting) saldırılarını önlemek için mutlaka içerik filtreleme ve temizleme (sanitization) işlemlerini gerçekleştirin.

Üretim ortamında (production), WebSocket bağlantılarını ölçeklendirmek için "Message Broker" olarak Redis veya RabbitMQ kullanmanız önerilir. Tek bir sunucu, binlerce eşzamanlı bağlantıyı yönetirken bellek darboğazı yaşayabilir.

Sıkça Sorulan Sorular

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

Bağlantı kopmaları genellikle ağ kesintileri veya sunucu tarafındaki "idle timeout" (boşta kalma zaman aşımı) ayarlarından kaynaklanır. İstemci tarafında "heartbeat" (kalp atışı) mekanizmasını aktif ederek bağlantının canlı kalmasını sağlayabilirsiniz.

STOMP protokolü kullanmak zorunlu mu?

Zorunlu değildir ancak mesajların yönlendirilmesi, abonelik yönetimi ve hata ayıklama süreçlerini çok daha kolaylaştırdığı için endüstri standardı olarak kabul edilir.

Websocket üzerinden büyük dosyalar gönderilir mi?

Websocket, küçük ve hızlı mesajlar için optimize edilmiştir. Büyük dosya transferleri için HTTP tabanlı multipart form verilerini veya özel dosya sunucularını kullanmanız daha performanslı olacaktır.

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

Bu, sunucunuzun RAM ve CPU kapasitesine bağlıdır. Tek bir Java JVM örneği, uygun konfigürasyonla on binlerce eşzamanlı bağlantıyı destekleyebilir.

Mesajları veritabanına nasıl kaydederim?

Controller içerisinde mesajı işledikten sonra, bir Servis katmanı aracılığıyla veritabanı (JPA/Hibernate) işlemini tetikleyerek mesajları kalıcı hale getirebilirsiniz.

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

Gerçek zamanlı uygulamalarda, HTTP tabanlı geleneksel istek-yanıt döngüsünün aksine, bağlantı sürekli açık kaldığı için hata ayıklama süreci daha karmaşıktır. Bir mesajın neden ulaşmadığını veya bağlantının neden kesildiğini anlamak için sistemli bir yaklaşım izlemelisiniz.

İstemci Tarafı Loglama

Tarayıcı konsolu, Websocket trafiğini izlemek için en iyi dostunuzdur. Chrome Geliştirici Araçları'nda "Network" sekmesine giderek "WS" filtresini seçin. Burada gönderilen ve alınan tüm "frame" verilerini görebilirsiniz. Ancak, kod içerisinde daha detaylı hata yönetimi için şu yapıyı kullanın:


const socket = new SockJS('/ws-chat');
const stompClient = Stomp.over(socket);

stompClient.debug = function(str) {
    console.log("STOMP Hata Ayıklama: " + str);
};

stompClient.connect({}, function(frame) {
    console.log('Bağlantı başarılı: ' + frame);
}, function(error) {
    console.error('Bağlantı hatası: ' + error);
    // Burada bağlantı kopması durumunda otomatik yeniden bağlanma mantığı kurabilirsiniz.
});

Sunucu Tarafı Event Listener Kullanımı

Spring Boot üzerinde Websocket bağlantı durumlarını izlemek için SessionConnectedEvent ve SessionDisconnectEvent sınıflarını dinleyen bir bileşen oluşturmak, kullanıcıların ne zaman koptuğunu takip etmenizi sağlar:


@Component
public class WebSocketEventListener {

    private static final Logger logger = LoggerFactory.getLogger(WebSocketEventListener.class);

    @EventListener
    public void handleWebSocketConnectListener(SessionConnectedEvent event) {
        logger.info("Yeni bir Websocket bağlantısı alındı.");
    }

    @EventListener
    public void handleWebSocketDisconnectListener(SessionDisconnectEvent event) {
        StompHeaderAccessor headerAccessor = StompHeaderAccessor.wrap(event.getMessage());
        String username = (String) headerAccessor.getSessionAttributes().get("username");
        if(username != null) {
            logger.info("Kullanıcı ayrıldı: " + username);
        }
    }
}

Yüksek Trafikli Uygulamalar İçin Ölçeklendirme İpuçları

Tek bir sunucu üzerinde çalışan Websocket uygulaması, kullanıcı sayısı arttıkça bellek ve CPU darboğazına girer. Dağıtık bir mimariye geçiş yaparken aşağıdaki yöntemleri göz önünde bulundurmalısınız.

Redis Pub/Sub ile Mesaj Dağıtımı

Birden fazla sunucu (instance) kullandığınızda, A sunucusuna bağlı bir kullanıcı, B sunucusuna bağlı bir kullanıcıya mesaj gönderemez. Bu sorunu aşmak için harici bir mesaj aracısı (Message Broker) kullanmak zorunludur. Spring Boot ile Redis kullanarak bu yapıyı şu şekilde yapılandırabilirsiniz:


@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {

    @Override
    public void configureMessageBroker(MessageBrokerRegistry config) {
        // Redis veya RabbitMQ gibi bir broker entegrasyonu
        config.enableStompBrokerRelay("/topic", "/queue")
              .setRelayHost("localhost")
              .setRelayPort(61613)
              .setClientLogin("guest")
              .setClientPasscode("guest");
        config.setApplicationDestinationPrefixes("/app");
    }
}

Performans İçin İleri Seviye Tavsiyeler

  • Heartbeat (Kalp Atışı): STOMP protokolü, bağlantının canlı kalması için periyodik olarak "heartbeat" paketleri gönderir. Sunucu ve istemci tarafında bu süreleri (örneğin 10 saniye) optimize ederek gereksiz trafikten kaçının.
  • Mesaj Sıkıştırma: Çok büyük JSON verileri gönderiyorsanız, Websocket mesajlarını sıkıştırmak için permessage-deflate eklentisini sunucu ayarlarınızda aktif edin.
  • Yük Dengeleyici (Load Balancer) Ayarları: Nginx veya HAProxy kullanıyorsanız, Websocket bağlantılarının kopmaması için proxy_set_header Upgrade $http_upgrade; ve proxy_set_header Connection "upgrade"; ayarlarının yapıldığından emin olun.

Sonuç

Java ile Websocket kullanarak gerçek zamanlı sohbet uygulaması geliştirmek, doğru mimariyi kurduğunuzda oldukça verimli bir süreçtir. Bu rehberde, Spring Boot kullanarak bir sohbet sunucusunun temellerini, mesajlaşma protokollerini ve güvenlik gerekliliklerini öğrendiniz. Bir sonraki adım olarak, kullanıcıların çevrimiçi durumlarını (online/offline) takip eden bir "Presence" sistemi ekleyerek uygulamanızı daha profesyonel hale getirebilirsiniz.

Kod güvenliği sorumluluk reddi: Bu rehberdeki kod örnekleri eğitim amaçlıdır. Canlıya almadan önce tüm giriş verilerini doğrulamalı, yetkilendirme (authentication/authorization) katmanlarını eklemeli ve OWASP standartlarına uygun güvenlik testlerini yapmalısınız.

Bu yazıya tepkinizi paylaşın:
Deniz Arslan

On yıllık içerik üretim deneyimiyle karmaşık süreçleri herkesin anlayabileceği pratik rehberlere dönüştürüyorum. Günlük yaşamı kolaylaştıran çözümler üzerine uzmanlaşmış bir editörüm.

Yorumlar (0)

Yorum Yaz