IHS Strategic
Tüm Blog Yazıları
HowTo10 Eylül 2026•3 dk okuma

WebSockets ile Gerçek Zamanlı Bildirim ve Mesajlaşma Altyapısı: Adım Adım Modern Web Rehberi

Modern web uygulamaları için WebSockets tabanlı gerçek zamanlı bildirim ve mesajlaşma mimarisi kurma rehberi. Dijital ajanslar ve geliştiriciler için ölçeklenebilir adımlar.

S

Sistem Yöneticisi

Kıdemli Yazılım Mimarı

Giriş: Modern Web Trendleri ve Çift Yönlü İletişim

Geleneksel HTTP istek-cevap döngüsü, anlık veri akışı gerektiren uygulamalarda yetersiz kalır. Sürekli HTTP polling yapmak sunucu yükünü artırır, gecikmeyi (latency) yükseltir. Modern web mimarilerinde WebSocket protokolü (RFC 6455), tek bir TCP bağlantısı üzerinden tam çift yönlü (full-duplex) iletişim sunar. Bu rehber, yüksek trafikli projeler üreten her dijital ajans ve backend mühendisi için sıfırdan ölçeklenebilir bir bildirim/mesajlaşma katmanı kurmayı hedefler.

Mimari Tasarım ve Veri Akışı

Sağlam bir gerçek zamanlı altyapı şu temel bileşenlerden oluşur:

  • WebSocket Gateway: İstemci bağlantılarını yönetir, el sıkışmayı (handshake) doğrular.
  • Kimlik Doğrulama Katmanı: JWT veya session tabanlı token doğrulamasını bağlantı anında tamamlar.
  • Pub/Sub Dağıtım Katmanı: Çoklu sunucu/küme (cluster) ortamında mesajları Redis Pub/Sub üzerinden senkronize eder.

Adım 1: Node.js ile Temel WebSocket Sunucusu

Harici ağır framework'lere gerek kalmadan yerel HTTP modülü ve hafif ws kütüphanesiyle sunucuyu ayağa kaldırın:

const http = require('http');
const WebSocket = require('ws');

const server = http.createServer();
const wss = new WebSocket.Server({ noServer: true });

// Bağlantı havuzu
const clients = new Map();

server.on('upgrade', (request, socket, head) => {
  // Handshake sırasında auth kontrolü
  const url = new URL(request.url, `http://${request.headers.host}`);
  const token = url.searchParams.get('token');

  if (!token || !validateToken(token)) {
    socket.write('HTTP/1.1 401 Unauthorized\r\n\r\n');
    socket.destroy();
    return;
  }

  wss.handleUpgrade(request, socket, head, (ws) => {
    const userId = getUserIdFromToken(token);
    wss.emit('connection', ws, request, userId);
  });
});

wss.on('connection', (ws, request, userId) => {
  clients.set(userId, ws);
  ws.isAlive = true;

  ws.on('pong', () => { ws.isAlive = true; });

  ws.on('message', (data) => {
    handleIncomingMessage(userId, data);
  });

  ws.on('close', () => {
    clients.delete(userId);
  });
});

server.listen(8080);

Adım 2: Heartbeat (Ping/Pong) ve Bağlantı Sağlığı

Ağ kopmaları ve sessiz ölümleri (ghost connections) tespit etmek için periyodik kontrol zorunludur:

const interval = setInterval(() => {
  wss.clients.forEach((ws) => {
    if (ws.isAlive === false) return ws.terminate();
    ws.isAlive = false;
    ws.ping();
  });
}, 30000);

wss.on('close', () => clearInterval(interval));

Adım 3: İstemci Tarafı ve Otomatik Yeniden Bağlanma

Modern tarayıcı istemcisi, bağlantı koptuğunda exponential backoff ile tekrar denemelidir:

class RealtimeClient {
  constructor(url, token) {
    this.url = url;
    this.token = token;
    this.retryCount = 0;
    this.connect();
  }

  connect() {
    this.ws = new WebSocket(`${this.url}?token=${this.token}`);

    this.ws.onopen = () => {
      this.retryCount = 0;
    };

    this.ws.onmessage = (event) => {
      const payload = JSON.parse(event.data);
      this.dispatch(payload.event, payload.data);
    };

    this.ws.onclose = () => {
      const timeout = Math.min(1000 * Math.pow(2, this.retryCount), 30000);
      this.retryCount++;
      setTimeout(() => this.connect(), timeout);
    };
  }

  send(event, data) {
    if (this.ws.readyState === WebSocket.OPEN) {
      this.ws.send(JSON.stringify({ event, data }));
    }
  }
}

Adım 4: Yatay Ölçekleme (Redis Pub/Sub Entegrasyonu)

Sunucu sayısı birden fazlaya çıktığında, Kullanıcı A Sunucu 1'e, Kullanıcı B Sunucu 2'ye bağlı olabilir. Bu durumu çözmek için Redis Pub/Sub adaptörü devreye girer:

Kritik Kural: WebSocket sunucuları stateful'dur. Durumu sunucu belleğinde değil, merkezi bir katmanda (Redis) tutun.

  • Mesaj geldiğinde yerel sunucu mesajı Redis kanalına basar (PUBLISH).
  • Tüm sunucular aynı kanalı dinler (SUBSCRIBE).
  • Hedef kullanıcı hangi sunucuya bağlıysa o sunucu istemciye veriyi iletir.

Adım 5: Güvenlik ve Dayanıklılık

  • Origin Kontrolü: Sadece tanımlı domainlerden gelen bağlantıları kabul edin.
  • Payload Doğrulama: JSON parse işlemlerini try-catch içine alın, şema doğrulama (Zod vb.) kullanın.
  • Rate Limiting: İstemci başına saniyede gönderilebilecek mesaj sınırını belirleyin.

Sonuç

WebSockets, trendler arasında yer alan modern interaktif deneyimlerin çekirdeğidir. Bu kurulum; minimum bağımlılık, sıfır gereksiz soyutlama ve yatay büyümeye hazır bir temel sunar.